Lorsque l’on souhaite utiliser des patterns de développement tel que MVVM (Model View – View Model) il y a une chose à savoir maîtriser (parmi beaucoup d’autres), c’est les RoutedCommand. C’est objets vont nous permettre d’exécuter des actions lorsque des événements seront déclenchés dans l’interface utilisateur. Par exemple, lorsque vous allez cliquez sur un bouton, nous allons déclencher une action. Vous allez me dire, mais ça on sait déjà le faire de plusieurs manière :
Exemple A :
Côté XAML : <Button Content="Click Me!" Click="Button_Click" />
Côté code behind :
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello World!");
}
Exemple B :
En s’abonnant à l’événement Click directement dans le code behind : bt.Click += new RoutedEventHandler(Button_Click);
Utilisation simple des RoutedCommand
L’utilisation des patterns de développement, en particulier MVVM, nous insite à placer de moins en moins de code de ce style là (abonnement à des événements) dans le code behind. Voyons donc comment utiliser les RoutedCommand pour palier à ça. Une RoutedCommand est une classe qui implémente l’interface ICommand. Celle-ci posséde deux méthodes qui vont nous interesser, à savoir CanExecute et Execute. La première retourne un booléen disant si oui ou non l’action peut être déclenchée et la seconde représente l’action à exécuter.
Dans notre code behind, nous allons décrire une action qui permettra d’afficher un MessageBox (peu importe le déclencheur pour le moment) :
/// <summary>
/// Création de l'objet RoutedCommand.
/// </summary>
public static RoutedCommand HelloWorldCommand = new RoutedCommand();
/// <summary>
/// Détermine si la commande peut être exécutée ou non.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void HelloWorldCommandCanExecute(Object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
/// <summary>
/// Exécute l'action.
/// </summary>
/// <param name="target"></param>
/// <param name="e"></param>
public void HelloWorldCommandExecuted(Object target, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hello World!");
}
Afin de pouvoir utiliser cette commande lorsque nous cliquerons sur un bouton, nous allons devoir déclarer cette commande dans le code XAML de cette façon :
<Window.CommandBindings>
<CommandBinding Command="local:MainWindow.HelloWorldCommand"
CanExecute="HelloWorldCommandCanExecute"
Executed="HelloWorldCommandExecuted"/>
</Window.CommandBindings>
Maintenant, pour que celle-ci soit exécutée lorsque nous cliquons sur le boutton, nous devons associer cette commande à la propriété Command du Button : <Button Content="Click Me!" Command="local:MainWindow.HelloWorldCommand" />
Si vous cliquez sur le bouton, vous aurez un MessageBox avec inscrit “Hello World!”. Voilà, nous avons fait une première RoutedCommand de façon très simple. Allons un peu plus loin dans les possibilités offertes par ces objets.
Utilisation des CommandParameter
Ajoutons un TextBox à notre fenêtre. Nous allons afficher le texte du TextBox dans un MessageBox déclenché par le click du boutton, mais uniquement lorsqu’il y aura un texte dans le TextBox. Pour cela, passons le contenu du TextBox (propriété Text) en paramètre de la commande :
<StackPanel>
<TextBox x:Name="txtName" />
<Button Content="Click Me!"
Command="local:MainWindow.HelloWorldCommand"
CommandParameter="{Binding Path=Text, ElementName=txtName}" />
</StackPanel>
Nous allons lier la propriété CommandParameter à la propriété Text du contrôle txtName. Voici comment récupérer cette valeur dans le code C# :
/// <summary>
/// Détermine si la commande peut être exécutée ou non.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void HelloWorldCommandCanExecute(Object sender, CanExecuteRoutedEventArgs e)
{
// Il faut vérifier que nous avons bien un objet en paramètre.
if (e.Parameter == null) return;
// On récupére la valeur.
String value = e.Parameter.ToString();
// On autorise l'exécution de la commande uniquement
// si l'on a du texte.
e.CanExecute = value.Trim().Length > 0;
}
/// <summary>
/// Exécute l'action
/// </summary>
/// <param name="target"></param>
/// <param name="e"></param>
public void HelloWorldCommandExecuted(Object target, ExecutedRoutedEventArgs e)
{
if (e.Parameter == null) return;
String value = e.Parameter.ToString();
MessageBox.Show(String.Format("Hello {0}!", value));
}
Voilà le résultat :


L’activation / désactivation du boutton est effectuée automatiquement lorsque le contenu du TextBox change.
Utilisation des InputBindings
Enfin, voyons comment utiliser les racourcis clavier pour exécuter des commandes. Nous allons lier la touche Entrée du clavier à la commande HelloWorldCommand :
<Window.InputBindings>
<KeyBinding Key="Enter"
Command="local:MainWindow.HelloWorldCommand"
CommandParameter="{Binding Path=Text, ElementName=txtName}" />
</Window.InputBindings>
Lorsque vous appuyez sur la touche Entrée, si vous avez entré un texte dans le TextBox, la commande HelloWorldCommand se déclenchera.
Comme vous pouvez le constater, il est vraiment simple de créer ses propres commandes et de les utiliser dans vos applications WPF. Si vous souhaitez télécharger l’exemple que j’ai utilisé, cliquez sur le lien suivant : DemoCommandWPF.zip (55 ko).