C# WPF禁用DataGrid上的默认键绑定(好像从未定义过)

C# WPF禁用DataGrid上的默认键绑定(好像从未定义过),c#,wpf,xaml,datagrid,key-bindings,C#,Wpf,Xaml,Datagrid,Key Bindings,我想禁用DataGrid键的一些默认行为,以便用我自己改进的命令覆盖它。我如何才能禁用DataGrid的键绑定,就好像从来没有定义过一样? 例如,默认情况下,Enter键跳转到新行,我希望将焦点放在项目详细信息控件上。使用this.handled=true可以很容易地停止事件也可以防止任何自定义命令发生,这是问题的最小示例: public partial class MainWindow : Window { public class Model { public str

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

例如,默认情况下,
Enter
键跳转到新行,我希望将焦点放在项目详细信息控件上。使用
this.handled=true可以很容易地停止事件也可以防止任何自定义
命令发生,这是问题的最小示例:

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"/>
公共部分类主窗口:窗口
{
公共类模型{
公共字符串名称{get;set;}
公共int值{get;set;}
}
公共类TestCommand:ICommand{
公共事件处理程序CanExecuteChanged;
public bool CanExecute(对象参数)=>true;
public void Execute(对象参数)=>MessageBox.Show(“调用的命令”);
}
public ICommand EnterCommand{get;}=new TestCommand();
公共数字项目{
获取{返回新列表(){
新模型{Name=“Foo”,值=15},
新模型{Name=“Bar”,值=1},
新型号{Name=“Baz”,值=42},
新模型{Name=“Bar”,Value=100};}
}
公共主窗口(){InitializeComponent();}
私有void DataGrid_PreviewKeyDown(对象发送方,KeyEventArgs e)
{
如果(e.Key==Key.Enter)e.Handled=true;
}
}
//MainWindow.xaml,Window.Name=“Root”

当DataGrid处于焦点状态时按下
Enter
键时,应通过
调用
EnterCommand
,即在codebehind(ViewModel ommited for brewity)中无显式引用,并阻止DataGrid的默认行为,即不跳到下一行。

处理完
DataGrid
PreviewKeyDown
事件后,您可以通过编程方式引发另一个
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
        });
    }
}

显然,您不能禁用键绑定“就好像它们从来没有被定义过一样”。它们被定义,创建它们的代码也被执行。您可以做的是重写或禁用特定的行为,但不能“禁用”框架代码的执行。@mm8 true,我想以一种可以在引号中描述的方式重写键绑定,“就好像它们从来没有被定义过一样”。它是否实际取消订阅并不重要,重要的是它是否按需要进行操作(最后一个问题段落)。如果不先在代码隐藏、自定义控件或行为中编写一些代码,就不能在此处使用键绑定。@mm8键绑定在xaml的示例代码中定义(
)。应执行的自定义项,而不应执行默认项。我知道这将需要一些代码来实现,以及。。。这里的问题是它可能是哪种代码。有什么想法吗?