WPF 禁用 DataGrid 上的默认键绑定(就好像它从未被定义过一样)

WPF disable default keybinding on DataGrid (as if it was never defined)

我想禁用 DataGrid 键的一些默认行为,以便用我自己改进的命令覆盖它。我怎样才能禁用 DataGrid 的键绑定,就好像它们从来没有被定义过一样?

例如,Enter 键默认跳转到新行,我想改为关注项目详细信息控制。使用 this.handled = true; 停止事件很容易,但是也可以防止任何自定义 Command 发生,问题的最小示例:

public partial class MainWindow : Window
{
    public class Model {
        public string Name { get; set; }
        public int Value { get; set; }
    }

    public class TestCommand : ICommand {
        public event EventHandler CanExecuteChanged;
        public bool CanExecute(object parameter) => true;
        public void Execute(object parameter) => MessageBox.Show("Command invoked");
    }

    public ICommand EnterCommand { get; } = new TestCommand();
    public IEnumerable<Model> Items {
        get { return new List<Model>() {
                new Model { Name = "Foo", Value = 15 },
                new Model { Name = "Bar", Value = 1 },
                new Model { Name = "Baz", Value = 42 },
                new Model { Name = "Bar", Value = 100 } }; }
    }

    public MainWindow() { InitializeComponent(); }

    private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter) e.Handled = true;
    }
}

//MainWindow.xaml, Window.Name = "Root"
<Window.InputBindings>
    <KeyBinding Key="Enter" Command="{Binding EnterCommand, ElementName=Root}"/>
</Window.InputBindings>
<DataGrid ItemsSource="{Binding Items, ElementName=Root}" PreviewKeyDown="DataGrid_PreviewKeyDown"/>

当在 DataGrid 获得焦点时按下 Enter 键,EnterCommand 应该通过 <KeyBinding/> 调用,即 在代码隐藏中没有显式引用 ( ViewModel ommited for brewity) 和 DataGrid 的默认行为被阻止,即不跳到下一行。

您可以在处理完 DataGridPreviewKeyDown 事件后以编程方式引发另一个 KeyDownEvent 事件:

private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        e.Handled = true;
        RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(this), 0, Key.Enter)
        {
            RoutedEvent = Keyboard.KeyDownEvent
        });
    }
}