Commanding with Silverlight 4

One of Silverlight 4’s new feature is commanding support. Commanding and the MVVM pattern allow clean separation of XAML and C# code: an action can be associated to a control using the {Binding} markup, just as it is done with data. Silverlight 4’s buttons support commanding through the Command property. The following example shows how a ConfirmPurchaseCommand can be executed when the user clicks on the button. Note that there is no event handler for Click, no code for enabling/disabling the button, and no XAML code-behind at all: lean and mean stuff!

<Button Content="{Binding Path=ConfirmPurchaseDescription}"

       Command="{Binding Path=ConfirmPurchase}"

       CommandParameter="{Binding CouponCode}"/>

Commanding is supported by making certain controls automatically call members of the ICommand interface. Execute is called to invoke the action, while CanExecute is called to know wether the action is possible (for example, a button will disable itself if CanExecute returns false).

But, where do I put my code ?

The attached example implements two commands.

1. ConfirmOrderCommand implements ICommand directly in a class and toggles the result of CanExecute depending on the parameter (OrderId). Implementing ICommand directly should generally be avoided, but it is nevertheless a good exercise to grasp how ICommand works:

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 on the other hand, is a very simple ICommand implementation that defers ICommand’s calls to delegates (similar to Prism’s DelegateCommand or MVVM Light’s RelayCommand), to simplify the sample's code its CanExecute always returns true. Using delegates is the recommended way to go as it results in shorter, more readable code explicitely called from the view model:

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

void ConfirmOrder(string orderId)

{

    ConfirmOrder(orderId);

}

Silverlight 4 beta makes commands available only on controls deriving from ButtonBase, and they are executed only when buttons are clicked. The next post will demonstrate how to execute commands on any controls from any event using Blend triggers.

Silverlight4Commanding.zip