Implementing ICommand

The ICommand interface is part of the commanding system in Silverlight and is usually recognizable alongside the Model-View-ViewModel (MVVM) pattern. The MVVM pattern aids the developer to separate the UI layer (View) from the code layer (Model) using a connector in between (ViewModel). The commanding system allows us to wire business logic functionality directly to buttons on the UI layer using XAML. Now, you may be thinking that we can already do that using event handlers and writing code in the code behind file of our XAML, and you would be right. But think about a scenario where you have to use the button logic elsewhere in the application. You will need to write another even handler for the new button, copy the logic over from the old one, and wire the Click event of the new button to the new handler. Instead, by using the commanding system, you can bind a command to a button. The command logic is placed in the ViewModel layer, which means that any button on the view can bind to it. In the commanding system, you don't respond to a button's Click event anymore; you are binding a command to the button and allowing any button to execute it directly from the UI layer.

The ICommand interface is the heart of the commanding system. Every control that inherits from the button base class supports binding to the commands using it. Every command you'll build must inherit from the ICommand interface in order to be a bindable command. The Icommand interface exposes two methods and one event as follows:

  • CanExecute: This method returns true if the command is allowed to execute
  • Execute: This defines the method to call when the command is invoked
  • CanExecuteChanged: This is an event that gets raised when the CanExecute property changes

Every command we create that inherits from the ICommand interface must implement all of the methods and events of the interface.

Once we have a command, we bind the button's Command property to the name of the command we wish to run, as shown in the following code snippet:

<Button x:Name="btnCart" Height="23" Grid.Row="1"
Width="71"
Margin="0,5,4,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Content="Add to cart"
Command="{Binding MyCookiesCommand}" />

The button has no Click event handler, but instead it has its Command property bound to MycookiesCommand, which is an ICommand inherited class.

Let's see how we will work with the ICommand in an application.

Building your first ICommand

Before we go on building our example project, I would like to say the sample will not be built in MVVM standards in order to keep the simplicity of the example, and help you understand the core concepts of the commanding system. I strongly encourage you to read about the MVVM pattern on the MSDN magazine at http://msdn.microsoft.com/en-us/magazine/dd419663.aspx and check out Laurent Bugnion's MVVM Light Toolkit which, in my opinion, is the best MVVM helper toolkit available at http://www.galasoft.ch/mvvm/.

With that being said, let's go ahead and create our first command. Open the Chapter4-ICommand project in Visual Studio 2010. You can find the project in the downloadable content over at www.packtpub.com.

The project consists of a datagrid, bound to a collection of the CookieItem items. Each CookieItem contains three properties:

  • Name: The name of the cookie
  • Milk: A Boolean property that represents whether the cookie goes well with milk or not
  • StarFill: A SolidColorBrush property, which sets the background color of a star shape.

Other than the CookieItem class, the project contains another class called CookiesModel.cs. CookiesModel is where we are saving the instance of the selected cookie and initiating our command. Let's start by building and running the application. The following screenshot shows what your result should look like:

Building your first ICommand

What our command is going to do is to get the button to mark the favorite cookies on the datagrid, as shown in the preceding screenshot. Let's add the new command class. Right-click on Classes, and select Add and then Class. Name your class CookieCommand.cs. Make the new class inherit from the ICommand interface by changing the class declaration as follows:

public class CookieCommand:ICommand

Copy the following code snippet inside your new class:

public event EventHandler CanExecuteChanged;
public void OnCanExecuteChanged()
{
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
public bool CanExecute(object parameter)
{
if (parameter != null)
return true;
else
return false;
}
public void Execute(object parameter)
{
if (parameter != null)
{
(parameter as CookieItem).StarFill = new SolidColorBrush(Colors.Yellow);
}
}

Because, our class inherits from the ICommand interface, it has to implement its three properties—Execute, CanExecute, and CanExecuteChanged.

We've added an event for the CanExecuteChanged property, which the model will call whenever the selected CookieItem is changed. We are doing so, because we need to call the CanExecute method every time we change an item to check if the command should or should not be executable.

In our example, CanExecute performs a very basic check—if the parameter that is passed to it isn't null, then the command should be executable. In the real world, of course, this check should have more meat on its bones.

Our Execute method is also quite simple. Its job is to first check whether the parameter it has got isn't null, and then if it isn't, to cast it to CookieItem. This method also sets the StarFill property to a yellow fill.

That's all there is to our command. Now, it's time to connect the dots and bind it to the Button control in our UI layer.

Open the CookiesModel.cs file and add the following property just above the CookieItem one:

public CookieCommand MyCookieCommand { get; set; }

This is the property that will hold our command. Inside the class constructor, add the initialization code for the command:

/* init command */
MyCookieCommand = new CookieCommand();

All we have to do now is wire the button control to the command. Open MainPage.xaml, and add the following two properties to the Button control:

Command="{Binding MyCookieCommand}" CommandParameter="{Binding SelectedCookie}"

In the Command property, we are binding the new command we created (remember, the property name we set to it was MyCookieCommand). In the CommandParameter property, we are passing the instance of the currently selected grid row—SelectedCookie (which we defined in our model class). You can use this property to pass any kind of data you need to your command. This is the parameter argument that both the CanExecute and Execute methods of the command will have.

Everything is done! Build and run your project, and you should get the result, as shown in the following screenshot:

Building your first ICommand

Notice that the button is disabled. Because, we haven't selected any row yet, the CanExecute method of the command will return false, which causes the Silverlight runtime engine to set the command-associated button to the disabled mode.

As soon as a row is selected, the button will be enabled, and clicking it will paint the favorite star in the associated row of the datagrid yellow, as shown in the following screenshot:

Building your first ICommand

That concludes our ICommand implementation. We have created a command that inherits from the ICommand interface, binds it to a button using XAML, passes it a parameter, and finally executes it.

While this was quite a simple implementation of the commanding system of Silverlight, the MVVM pattern makes a much heavier use of it. As I stated in the beginning of the topic, I highly suggest you go and learn more about this pattern, as not only is this one of the most popular patterns of Silverlight, it is also the base of clean and neat code that helps you separate your code from your UI.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.10.32