代码之家  ›  专栏  ›  技术社区  ›  Joseph Sturtevant

WPF文本框拦截路由命令

  •  11
  • Joseph Sturtevant  · 技术社区  · 15 年前

    Command Pattern 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!"); }
        }
    }
    
    6 回复  |  直到 7 年前
        1
  •  11
  •   stakx - no longer contributing Saravana Kumar    13 年前

    没有直接的方法来抑制所有绑定,不要设置 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;
    }
    
        2
  •  5
  •   MRoc    14 年前

    如果要实现自己的撤消/重做并防止文本框拦截,请通过附加到命令预览事件 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;
        }
    }
    
        3
  •  1
  •   AndyM    15 年前

    默认情况下,目标 RoutedUICommand CommandTarget 在发出命令的控件上,以更改接收命令的根元素。

    <MenuItem Command="ApplicationCommands.Open"
              CommandTarget="{Binding ElementName=UIRoot}"
              Header="_Open" />
    
        4
  •  1
  •   Mark Synowiec    15 年前

    执行的事件会出现气泡,因此窗口执行的事件将始终在TextBox执行的事件之后命中。尝试将其更改为PreviewExecuted,它将产生巨大的变化。此外,您可能还需要为您的窗口连接CanExecute。即:

    <CommandBinding Command="Undo" PreviewExecuted="MyUndo_Executed" CanExecute="SomeOtherFunction"/>
    
    private void SomeOtherFunction(object sender, ExecutedRoutedEventArgs e) { e.CanExecute=true; }
    

    当然,您可能需要一些逻辑来确定何时将CanExecute设置为true。您可能也不需要使用自定义命令(只需使用内置的Undo)。

        5
  •  0
  •   Pavel Minaev    15 年前

    TextBoxBase TextBox RichTextBox )有 IsUndoEnabled 属性,默认为 true false (和往常一样,您可以通过样式和setter对窗口上的所有文本框执行事件设置),这样它们就不会拦截Ctrl+Z。

        6
  •  0
  •   Jasper wontondon    13 年前

    这个 TextBox 控件提供了 IsUndoEnabled 可以设置为 false 以防止撤消功能。(如果 true + Z

    然后可以提供一个新的 CanExecute 总是响应false的事件处理程序。这里有一个

    CommandBinding commandBinding = new CommandBinding(
    ApplicationCommands.Cut, null, SuppressCommand);
    txt.CommandBindings.Add(commandBinding);
    

    下面是设置 声明:

    private void SuppressCommand(object sender, CanExecuteRoutedEventArgs e)
    {
      e.CanExecute = false;
      e.Handled = true;
    }