Я хотел бы отключить некоторые функции клавиш DataGrid
по умолчанию, чтобы заменить их своими улучшенными командами. Как я могу отключить сочетания клавиш DataGrid
, как если бы они никогда не были определены в первую очередь?
Например, клавиша Enter
по умолчанию переходит к новой строке, вместо этого я хотел бы сфокусировать управление деталями элемента. Остановить событие достаточно просто с помощью this.handled = true;
, что, однако, также предотвращает возникновение любых пользовательских Command
s, минимальный пример проблемы:
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"/>
Когда клавиша Enter
нажата, когда DataGrid находится в фокусе, EnterCommand
должен вызываться через <KeyBinding/>
, то есть без явной ссылки в отделенном коде (ViewModel опущен для простоты), а поведение DataGrid по умолчанию предотвращается, то есть не переходит к следующей строке.
@ mm8 правда, я хотел бы переопределить привязки клавиш таким образом, который можно было бы описать как в цитате «как если бы они никогда не были определены в первую очередь». Не важно, отписывается ли он на самом деле от чего-то, важно, что он действует так, как хочет (последний абзац вопроса).
Вы не можете использовать здесь привязки клавиш без предварительного написания некоторого кода в коде программной части, пользовательском элементе управления или в поведении.
@ mm8 Привязка клавиш определяется в примере кода в xaml (<Window.InputBindings>
). Пользовательский, который должен выполняться, а по умолчанию - нет. Я знаю, что для этого потребуется некоторый код, и, ну... вопрос в том, какой это может быть код. Есть идеи?
Вы можете программно вызвать другое событие KeyDownEvent
после обработки события DataGrid
PreviewKeyDown
:
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
});
}
}
Очевидно, вы не можете отключить привязки клавиш, «как если бы они никогда не были определены в первую очередь». Они определены как являются, и код, создающий их делает, выполняется. Что вы можете сделать, так это переопределить или отключить определенное поведение, но вы не можете «отключить» выполнение кода фреймворка.