问题 WPF TextBox拦截RoutedUICommands
我试图在我的WPF应用程序中使用Undo / Redo键盘快捷键(我有自己的自定义功能使用 命令模式)。然而,似乎是 TextBox
控制是拦截我的“撤消”RoutedUICommand。
什么是禁用此功能的最简单方法,以便我可以在UI树的根目录中捕获Ctrl + Z?我想避免将大量代码/ XAML放入每个代码中 TextBox
如果可能,在我的申请中。
以下简要说明问题:
<Window x:Class="InputBindingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:InputBindingSample"
Title="Window1" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding Command="loc:Window1.MyUndo" Executed="MyUndo_Executed" />
</Window.CommandBindings>
<DockPanel LastChildFill="True">
<StackPanel>
<Button Content="Ctrl+Z Works If Focus Is Here" />
<TextBox Text="Ctrl+Z Doesn't Work If Focus Is Here" />
</StackPanel>
</DockPanel>
</Window>
using System.Windows;
using System.Windows.Input;
namespace InputBindingSample
{
public partial class Window1
{
public static readonly RoutedUICommand MyUndo = new RoutedUICommand("MyUndo", "MyUndo", typeof(Window1),
new InputGestureCollection(new[] { new KeyGesture(Key.Z, ModifierKeys.Control) }));
public Window1() { InitializeComponent(); }
private void MyUndo_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("MyUndo!"); }
}
}
1529
2017-09-03 19:36
起源
答案:
没有简单的方法来压制所有绑定,不要设置 IsUndoEnabled
至 false
因为它只会陷阱和冲洗 按Ctrl + ž 键绑定。你需要重定向 CanUndo
, CanRedo
, Undo
和 Redo
。这就是我用我的方式做的 UndoServiceActions
单身。
textBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo,
UndoCommand, CanUndoCommand));
textBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo,
RedoCommand, CanRedoCommand));
private void CanRedoCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = UndoServiceActions.obj.UndoService.CanRedo;
e.Handled = true;
}
private void CanUndoCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = UndoServiceActions.obj.UndoService.CanUndo;
e.Handled = true;
}
private void RedoCommand(object sender, ExecutedRoutedEventArgs e)
{
UndoServiceActions.obj.UndoService.Redo();
e.Handled = true;
}
private void UndoCommand(object sender, ExecutedRoutedEventArgs e)
{
UndoServiceActions.obj.UndoService.Undo();
e.Handled = true;
}
10
2018-05-23 05:42
答案:
没有简单的方法来压制所有绑定,不要设置 IsUndoEnabled
至 false
因为它只会陷阱和冲洗 按Ctrl + ž 键绑定。你需要重定向 CanUndo
, CanRedo
, Undo
和 Redo
。这就是我用我的方式做的 UndoServiceActions
单身。
textBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo,
UndoCommand, CanUndoCommand));
textBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo,
RedoCommand, CanRedoCommand));
private void CanRedoCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = UndoServiceActions.obj.UndoService.CanRedo;
e.Handled = true;
}
private void CanUndoCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = UndoServiceActions.obj.UndoService.CanUndo;
e.Handled = true;
}
private void RedoCommand(object sender, ExecutedRoutedEventArgs e)
{
UndoServiceActions.obj.UndoService.Redo();
e.Handled = true;
}
private void UndoCommand(object sender, ExecutedRoutedEventArgs e)
{
UndoServiceActions.obj.UndoService.Undo();
e.Handled = true;
}
10
2018-05-23 05:42
如果要实现自己的撤消/重做并阻止TextBox拦截,请附加到命令预览事件 CommandManager.AddPreviewCanExecuteHandler
和 CommandManager.AddPreviewExecutedHandler
并将event.Handled标志设置为true:
MySomething()
{
CommandManager.AddPreviewCanExecuteHandler(
this,
new CanExecuteRoutedEventHandler(OnPreviewCanExecuteHandler));
CommandManager.AddPreviewExecutedHandler(
this,
new ExecutedRoutedEventHandler(OnPreviewExecutedEvent));
}
void OnPreviewCanExecuteHandler(object sender, CanExecuteRoutedEventArgs e)
{
if (e.Command == ApplicationCommands.Undo)
{
e.CanExecute = true;
e.Handled = true;
}
else if (e.Command == ApplicationCommands.Redo)
{
e.CanExecute = true;
e.Handled = true;
}
}
void OnPreviewExecutedEvent(object sender, ExecutedRoutedEventArgs e)
{
if (e.Command == ApplicationCommands.Undo)
{
// DO YOUR UNDO HERE
e.Handled = true;
}
else if (e.Command == ApplicationCommands.Redo)
{
// DO YOUR REDO HERE
e.Handled = true;
}
}
5
2018-06-28 22:06
TextBoxBase
(因此 TextBox
和 RichTextBox
)有 IsUndoEnabled
财产,违约 true
。如果你把它设置为 false
(并且您可以像往常一样通过样式和设置器对窗口上的所有文本框执行此操作),然后它们将不会拦截Ctrl + Z.
0
2017-09-03 19:43
默认情况下是目标 RoutedUICommand
是具有键盘焦点的元素。但是,你可以设置 CommandTarget
在发出命令的控件上,以便更改接收命令的根元素。
<MenuItem Command="ApplicationCommands.Open"
CommandTarget="{Binding ElementName=UIRoot}"
Header="_Open" />
0
2017-09-03 19:53
Executed事件冒泡,因此在TextBox Executed事件之后将始终触发Window Executed事件。尝试将其更改为PreviewExecuted,它应该会产生巨大的差异。此外,您可能还需要为窗口连接CanExecute。即:
<CommandBinding Command="Undo" PreviewExecuted="MyUndo_Executed" CanExecute="SomeOtherFunction"/>
private void SomeOtherFunction(object sender, ExecutedRoutedEventArgs e) { e.CanExecute=true; }
当然,您可能需要一些逻辑来确定CanExecute何时应设置为true。您可能也不需要使用自定义命令(只需使用内置的撤消)。
0
2017-09-03 20:13
该 TextBox
控制提供了一个 IsUndoEnabled
你的财产
可以设置为 false
防止撤消功能。 (如果 IsUndoEnabled
是 true
, 按Ctrl + ž 击键触发它。)
此外,对于不提供特殊属性的控件,您可以为要禁用的命令添加新绑定。这种约束力
然后可以提供新的 CanExecute
始终响应false的事件处理程序。这是一个
使用此技术删除对文本框的剪切功能的支持的示例:
CommandBinding commandBinding = new CommandBinding(
ApplicationCommands.Cut, null, SuppressCommand);
txt.CommandBindings.Add(commandBinding);
这是设置的事件处理程序 CanExecute
州:
private void SuppressCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
0
2017-09-03 19:44