Liaison D'une clé de raccourci WPF à une commande dans le ViewModel

j'ai une application WPF qui utilise le modèle MVVM. Accrocher des boutons à la VM est assez simple puisqu'ils mettent en œuvre L'ICommand. J'ai un menu contextuel qui fonctionne de manière similaire. L'étape suivante consiste à créer des touches de raccourci pour le menu contextuel. Je ne sais pas comment faire pour que la touche de raccourci invoque la commande. Voici un exemple:

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

maintenant, j'ai ajouté ceci:

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

pour essayer de connecter les touches de raccourci à la même reliure, mais cela ne fonctionne pas. L'erreur est:

erreur 169 un' Binding 'ne peut pas être défini sur la propriété' Command 'de type'KeyBinding'. Un "Binding" ne peut être défini que sur une propriété Dependenced'un objet Dependencyob.

N'y a-t-il pas un moyen de relier cet événement à la commande? Je ne peux pas comprendre cela.

merci d'avance!

projet de Loi

36
demandé sur JiBéDoublevé 2010-03-05 00:40:56

5 réponses

j'ai écrit un personnaliser l'extension de balisage pour "lier" InputBindings aux commandes, qui peuvent être utilisées presque comme une vraie liaison:

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

notez que cette extension markup utilise la réflexion privée, elle ne peut donc être utilisée que si votre application fonctionne en toute confiance...

une Autre option est d'utiliser le CommandReference classe. Il peut être trouvé dans la boîte à outils MVVM disponible ici. C'est probablement un nettoyant approche, mais un peu plus complexe à utiliser.

notez que dans WPF 4, le InputBinding.Command,InputBinding.CommandParameter et InputBinding.CommandTarget les propriétés sont des propriétés de dépendances, donc elles peuvent être liées normalement

27
répondu Thomas Levesque 2014-12-09 12:51:42

Le code suivant peut être utilisé pour lier une touche de raccourci directement à une commande:

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

ajouter ceci après la fenêtre.Ressources dans le code XAML de votre vue.

35
répondu Michel Keijzers 2014-04-23 17:24:26

je suis d'accord que le faire dans XAML est idéal, mais pour des raisons d'exhaustivité, vous pouvez également ajouter votre reliure en code. Si vous le faites dans le constructeur, assurez-vous simplement que c'est après l'appel à InitializeComponent()

InputBindings.Add(new KeyBinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control));
8
répondu Eddie Deyo 2015-02-18 21:45:27

une approche alternative pour lier une touche de raccourci WPF à une propriété de commande du ViewModel est montrée dans l'exemple de raccourciWPF Cadre applicatif (WAF) projet.

0
répondu jbe 2010-03-07 19:12:01

ont été en mesure d'ajouter un lien de clé au niveau du DataGrid. Comme ceci :

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>

Modèle De Vue :

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 ;
}
0
répondu Tesfay K. Aregay 2016-08-08 10:14:37