Связывание ключа WPF ShortCut с командой в ViewModel
У меня есть приложение WPF, которое использует шаблон MVVM. Подсоединение кнопок к виртуальной машине довольно прямолинейно, поскольку они реализуют ICommand. У меня есть контекстное меню, которое работает аналогично. Следующим шагом будет создание сочетаний клавиш для контекстного меню. Я не могу понять, как заставить клавишу быстрого вызова вызвать команду. Вот пример:
<MenuItem Header="Update" Command="{Binding btnUpdate}" >
<MenuItem.Icon>
<Image Source="/Images/Update.png"
Width="16"
Height="16" />
</MenuItem.Icon>
</MenuItem>
теперь я добавил это:
<Window.InputBindings>
<KeyBinding Key="U"
Modifiers="Control"
Command="{Binding btnUpdate}" />
</Window.InputBindings>
чтобы попытаться подключить сочетания клавиш к одной и той же привязке, но это не сработает. Ошибка:
Ошибка 169 "Связывание" не может быть задано в свойстве "Command" типа "KeyBinding". "Связывание" может быть установлено только в DependencyProperty объекта DependencyObject.
Нет ли способа подключить это событие к команде? Я не могу понять это.
заблаговременно!
Билл
Ответы
Ответ 1
Я написал настраиваемое расширение разметки для привязки InputBindings
к командам, которые можно использовать почти как реальное связывание:
<UserControl.InputBindings>
<KeyBinding Modifiers="Control"
Key="E"
Command="{input:CommandBinding EditCommand}"/>
</UserControl.InputBindings>
Обратите внимание, что это расширение разметки использует частное отражение, поэтому его можно использовать только в том случае, если ваше приложение работает с полным доверием...
Другой вариант - использовать класс CommandReference
. Его можно найти в наборе инструментов MVVM здесь. Это, вероятно, более чистый подход, но немного сложнее в использовании.
Обратите внимание, что в WPF 4 свойства InputBinding.Command
, InputBinding.CommandParameter
и InputBinding.CommandTarget
являются свойствами зависимостей, поэтому они могут быть связаны нормально
Ответ 2
Следующий код может использоваться для привязки клавиши быстрого доступа непосредственно к команде:
<Window.InputBindings>
<KeyBinding Command="{Binding Path=NameOfYourCommand}"
Key="O"
Modifiers="Control"/>
</Window.InputBindings>
Добавьте это после Window.Resources в код XAML вашего представления.
Ответ 3
Я согласен, что делать это в XAML идеально, но для полноты вы можете добавить свою привязку в код. Если вы сделаете это в конструкторе, просто убедитесь, что это после вызова InitializeComponent()
InputBindings.Add(new KeyBinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control));
Ответ 4
Альтернативный подход для привязки ключа ярлыка WPF к свойству Command ViewModel показан в примере ShortcutKey WPF Application Framework ( WAF).
Ответ 5
Могли добавить Keybinding на уровне DataGrid. Вот так:
Xaml:
<DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding YourCollection}"
CanUserAddRows="False"
HeadersVisibility="Column"
CanUserDeleteRows="False"
CanUserSortColumns="True"
CanUserResizeRows="False"
CanUserResizeColumns="False"
SelectedItem="{Binding YourSelectedItem}"
SelectionMode="Single"
SelectionUnit="FullRow"
>
<DataGrid.ContextMenu>
<ContextMenu>
**<MenuItem Header="Delete" InputGestureText="Del" Command="{Binding DeleteCommand}">**
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
**<DataGrid.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteCommand}" CommandParameter="Delete"/>**
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="Column Header" Binding="{Binding YourColumn}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
Просмотр модели:
public ICommand DeleteCommand
{
get
{
return new DelegateCommand(ExecuteCommand, CanExecute);
}
}
private void ExecuteCommand()
{
// your code to delete here.
YourCollection.Remove(YourSelectedItem);
}
private void CanExecute()
{
// logic to check if the delete command can execute.
return YourSelectedItem != null ;
}