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 的默认行为被阻止,即不跳到下一行。
您可以在处理完 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
});
}
}
我想禁用 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 的默认行为被阻止,即不跳到下一行。
您可以在处理完 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
});
}
}