example commandmanager data-binding mvvm shortcuts

data-binding - commandmanager - icommand wpf



Enlazar una tecla de acceso directo de WPF a un comando en el modelo de vista (5)

Tengo una aplicación WPF que está usando el patrón MVVM. Conectar los botones a la VM es bastante directo ya que implementan ICommand. Tengo un menú contextual que funciona de manera similar. El siguiente paso es crear teclas de método abreviado para el menú contextual. No puedo entender cómo hacer que la tecla de acceso directo invoque el comando. Aquí hay un ejemplo:

<MenuItem Header="Update" Command="{Binding btnUpdate}" > <MenuItem.Icon> <Image Source="/Images/Update.png" Width="16" Height="16" /> </MenuItem.Icon> </MenuItem>

ahora he agregado esto:

<Window.InputBindings> <KeyBinding Key="U" Modifiers="Control" Command="{Binding btnUpdate}" /> </Window.InputBindings>

intentar y conectar las teclas de acceso directo al mismo enlace, pero esto no funciona. El error es:

Error 169 Un "Enlace" no puede establecerse en la propiedad "Comando" de tipo "Enlace de clave". Un ''Enlace'' solo se puede establecer en una DependencyProperty de un DependencyObject.

¿No hay una forma de conectar este evento con el Comando? No puedo resolver esto.

¡gracias por adelantado!

Cuenta


El siguiente código se puede usar para vincular una tecla de método abreviado directamente a un comando:

<Window.InputBindings> <KeyBinding Command="{Binding Path=NameOfYourCommand}" Key="O" Modifiers="Control"/> </Window.InputBindings>

Agregue esto después de Window.Resources en el código XAML de su vista.


En el ejemplo de ShortcutKey del proyecto WPF Application Framework (WAF) se muestra un enfoque alternativo para enlazar una clave de acceso directo de WPF a una propiedad Command del ViewModel.


Escribí una extensión de marcado personalizado para "enlazar" InputBindings a comandos, que se pueden usar casi como un enlace real:

<UserControl.InputBindings> <KeyBinding Modifiers="Control" Key="E" Command="{input:CommandBinding EditCommand}"/> </UserControl.InputBindings>

Tenga en cuenta que esta extensión de marcado utiliza reflexión privada, por lo que solo se puede usar si su aplicación se ejecuta con plena confianza ...

Otra opción es usar la clase CommandReference . Se puede encontrar en el kit de herramientas MVVM disponible here . Probablemente sea un enfoque más limpio, pero un poco más complejo de usar.

Tenga en cuenta que en WPF 4, las InputBinding.Command , InputBinding.CommandParameter y InputBinding.CommandTarget son propiedades de dependencia, por lo que pueden vincularse normalmente.


Estoy de acuerdo en que hacerlo en XAML es ideal, pero para completar, también puedes agregar tu enlace en el código. Si lo haces en el constructor, solo asegúrate de que esté después de la llamada a InitializeComponent()

InputBindings.Add(new KeyBinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control));


Se ha podido agregar Keybinding en el nivel DataGrid. Me gusta esto :

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>

Ver modelo:

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 ; }