I would like to disable some of the default behaviours of DataGrid
keys in order to override it with my own improved commands. How can I disable DataGrid
's keybinds as if they were never defined in the first place?
For example, Enter
key jumps to new row by default, I would like to focus item detail control instead. Stopping the event is easy enough with this.handled = true;
that, however also prevents any custom Command
s from happening, minimal example of the problem:
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"/>
When Enter
key is pressed while DataGrid is focused, EnterCommand
should be invoked via <KeyBinding/>
i.e. without explicit reference in codebehind (ViewModel ommited for brewity) and DataGrid's default behaviour prevented, i.e. not jumping to next row.
You could programmatically raise another KeyDownEvent
event once you have handled the DataGrid
's PreviewKeyDown
event:
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
});
}
}