Silverlight Feeds - All your Silverlight feeds in one place.

Sponsors

Monday, February 22, 2010

5 Simple Steps to Commanding in Silverlight

by John Papa via JohnPapa.net on 2/22/2010 9:53:00 PM

Implementing ICommand in your Silverlight 4 project only requires a few steps. I have had a dozens of questions about this lately so I decided to share a very simple technique to implement commanding in Silverlight 4.

Step 1 – Implement ICommand

The first step is to implement the ICommand interface with a class that will manage the commanding aspects. There are other options to do this, but here is a simplified yet powerful implementation of ICommand.

The DelegatedCommand class implements ICommand’s CanExecute method, the Execute method, and the CaneExecuteChanged event. This code can be copied and used “as is”.

   1: public class DelegateCommand : ICommand
   2: {
   3:     Func<object, bool> canExecute;
   4:     Action<object> executeAction;
   5:     bool canExecuteCache;
   6:  
   7:     public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute)
   8:     {
   9:         this.executeAction = executeAction;
  10:         this.canExecute = canExecute;
  11:     }
  12:  
  13:     #region ICommand Members
  14:  
  15:     public bool CanExecute(object parameter)
  16:     {
  17:         bool temp = canExecute(parameter);
  18:  
  19:         if (canExecuteCache != temp)
  20:         {
  21:             canExecuteCache = temp;
  22:             if (CanExecuteChanged != null)
  23:             {
  24:                 CanExecuteChanged(this, new EventArgs());
  25:             }
  26:         }
  27:  
  28:         return canExecuteCache;
  29:     }
  30:  
  31:     public event EventHandler CanExecuteChanged;
  32:  
  33:     public void Execute(object parameter)
  34:     {
  35:         executeAction(parameter);
  36:     }
  37:  
  38:     #endregion
  39: }

Step 2 – Define the Command

Add a public property to your ViewModel to represent the ICommand. This property will be bound to your View through a button, generally.

public ICommand LoadProductsCommand { get; set; }

Step 3 – Create the Command

In the constructor of your ViewModel, set the command property you created in step 1.

LoadProductsCommand = new DelegateCommand(LoadProducts, CanLoadProducts);

Step 4 – Create the VM

You must then make sure your ViewModel is accessible in your View. This is can be done in many ways. But for simplicity I am showing the ViewModel created as a static resource in the View’s XAML.

<UserControl.Resources>
    <local:ProductViewModel x:Key="vm"/>
</UserControl.Resources>

Step 5 – Bind the Command

Add a button control and bind the Command property to the command you created in the ViewModel. Then if you need to pass a parameter into the command you can bind the CommandParameter property to an element in the View. I find that I generally do not need to pass a parameter in, but I added this here as an example.

<Button Content="Load" Width="120"
    Command="{Binding LoadProductsCommand}"
    CommandParameter="{Binding ElementName=FilterTextBox, Path=Text}" />

That’s it! 5 simple steps and now you have commanding in your application.

Want More …

I included the key code files in the post, below. No need to dive into them unless you want to grab the code as a starting point.

The complete ProductViewModel code can be seen here:

   1: public class ProductViewModel : ViewModelBase
   2: {
   3:     public ProductViewModel()
   4:     {
   5:         this.Products = new ObservableCollection<Product>();
   6:  
   7:         // Warning: DEMO CODE AHEAD
   8:         // Your ViewModel should not define your data for your Model :-)
   9:         // Instead, it could make a call to a service to get the data for the Model.
  10:         this.AllProducts = new ObservableCollection<Product>();
  11:         this.AllProducts.Add(new Product { ProductId = 1, ProductName = "Apple" });
  12:         this.AllProducts.Add(new Product { ProductId = 2, ProductName = "Orange" });
  13:         this.AllProducts.Add(new Product { ProductId = 3, ProductName = "Banana" });
  14:         this.AllProducts.Add(new Product { ProductId = 4, ProductName = "Pear" });
  15:         this.AllProducts.Add(new Product { ProductId = 5, ProductName = "Grape" });
  16:         this.AllProducts.Add(new Product { ProductId = 6, ProductName = "Grapefruit" });
  17:         this.AllProducts.Add(new Product { ProductId = 7, ProductName = "Strawberry" });
  18:         this.AllProducts.Add(new Product { ProductId = 8, ProductName = "Melon" });
  19:         this.AllProducts.Add(new Product { ProductId = 9, ProductName = "Guava" });
  20:         this.AllProducts.Add(new Product { ProductId = 10, ProductName = "Kiwi" });
  21:         this.AllProducts.Add(new Product { ProductId = 11, ProductName = "Pineapple" });
  22:         this.AllProducts.Add(new Product { ProductId = 12, ProductName = "Mango" });
  23:  
  24:         LoadProductsCommand = new DelegateCommand(LoadProducts, CanLoadProducts);
  25:     }
  26:  
  27:     private void LoadProducts(object param)
  28:     {
  29:         string filter = param as string ?? string.Empty;
  30:         this.Products.Clear();
  31:         var query = from p in this.AllProducts
  32:                     where p.ProductName.ToLower().StartsWith(filter.ToLower())
  33:                     select p;
  34:         foreach (var item in query)
  35:         {
  36:             this.Products.Add(item);
  37:         }
  38:     }
  39:  
  40:     private bool CanLoadProducts(object param)
  41:     {
  42:         return true;
  43:     }
  44:  
  45:     public ICommand LoadProductsCommand { get; set; }
  46:  
  47:     public ObservableCollection<Product> AllProducts { get; set; }
  48:  
  49:     private ObservableCollection<Product> products;
  50:     public ObservableCollection<Product> Products
  51:     {
  52:         get
  53:         {
  54:             return products;
  55:         }
  56:         set
  57:         {
  58:             products = value;
  59:             this.FirePropertyChanged("Product");
  60:         }
  61:     }
  62: }
  63:  

Here is the ViewModelBase class. It simply contains the FirePropertyChanged event that all ViewModel classes will use in my project.

   1: public abstract class ViewModelBase : INotifyPropertyChanged
   2: {
   3:     public ViewModelBase()
   4:     {
   5:     }
   6:  
   7:     public event PropertyChangedEventHandler PropertyChanged;
   8:  
   9:     protected void FirePropertyChanged(string propertyname)
  10:     {
  11:         var handler = PropertyChanged;
  12:         if (handler != null)
  13:             handler(this, new PropertyChangedEventArgs(propertyname));
  14:     }
  15:  
  16: }
email it!bookmark it!digg it!

Original Post: 5 Simple Steps to Commanding in Silverlight

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us