Silverlight 4 et les commandes

Une des nouvelles fonctionnalités de Silverlight 4 concerne les commandes. Celles-ci permettent, en les combinant avec le pattern MVVM, d’obtenir une séparation stricte en le XAML et le code C#: une action peut être associée à un contrôle par une notation {Binding}, exactement de la même manière que sont associées les données. Les boutons de Silverlight 4 intègre les commandes par le biais de leur propriété Command. L’exemple suivant montre comment la commande ConfirmPurchaseCommand sera exécutée lorsque l’utilisateur clique sur le bouton. Notez qu’il n’y a pas d’EventHandler sur le Click, pas de code pour activer/désactiver le bouton, et pas du tout de code-behind associé au fichier XAML: une séparation parfaite!

<Button Content="{Binding Path=ConfirmPurchaseDescription}" 
        Command="{Binding Path=ConfirmPurchase}"
        CommandParameter="{Binding CouponCode}"/>

Le système de commandes (“commanding”) est intégré par certains contrôles en faisant en sorte que sous certaines conditions (par exemple le clic pour un bouton) les membres de l’interface ICommand soient appelés. Execute est appelé pour invoquer une action, tandis que le résultat de CanExecute est utilisé pour déterminer si l’action est possible. Dans le cas des boutons, ceux-ci se grisent lorsque CanExecute renvoit false.

Mais, où puis-je mettre mon code alors ?

Le projet exemple attaché implémente deux commandes de manières différentes.

1. ConfirmOrderCommand implémente ICommand directement dans une classe, et renvoit une valeur différente pour son CanExecute en fonction de son paramètre OrderId. Implémenter une commande de cette manière n’est en général pas recommandé, mais est un bon exercice permettant de comprendre le fonctionnement d’ICommand.

public class CancelOrderCommand: ICommand
{
    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter) { return ((parameter as string) == "0123456789"); }

    public void Execute(object parameter)
    { /* CancelOrder(parameter..); */ }
}

2. CommandImpl, le deuxième exemple d’implémentation, est défère les méthodes d’ICommand à des delegates (à la manière des DelegateCommand de Prism et du RelayCommand de MVVM Light). Afin de simplifier le code exemple, CanExecute renvoit ici toujours true. L’utilisation de delegates est la manière usuelle de procéder: elle résulte en du code plus court, plus lisible et appellé explicitement depuis le viewmodel :

this.ConfirmOrderCommand = new CommandImpl<string>(ConfirmOrder);

void ConfirmOrder(string orderId)
{
    ConfirmOrder(orderId);
}

Silverlight 4 beta permet l’utilisation de commandes seulement sur les contrôles dérivant de ButtonBase, et elles ne sont appelées que lorsque les boutons sont cliqués. Le prochain post montrera comment exécuter des commandes depuis n’importe quel contrôle et évènement en utilisant le SDK Expression Blend.

Silverlight4Commanding.zip