Posted by: Zeeshan Amjad | January 19, 2010

Command Binding with Parameter Passing


We saw the example of command binding to calculate the GCD and LCM of two input numbers. Now lets extend this idea and trying to pass some parameter while doing command binding. We have the same signature of calculating LCM and GCD so we are passing one parameter during the command binding to decide which function to call. Let’s take a look at our numbers class now. It is very simple and the difference is now we are making only one property of ICommand rather than two because we are binding only one method. And that method internally calls two different methods depends on parameter. This is again ground work for MVVM.

Here is our Number class.

  1: public class Numbers
  2: {
  3:     public int FirstNo
  4:     { get; set; }
  5: 
  6:     public int SecondNo
  7:     { get; set; }
  8: 
  9:     public ICommand CalculateCommand
 10:     { get; set; }
 11: }
 12: 

Now we implement the ICommand nterface but this time our function take String as a parameter. Here is our command class.

  1: public class MyCommand : ICommand
  2: {
  3:     public Func<String, int> Function
  4:     { get; set; }
  5: 
  6:     public bool CanExecute(object parameter)
  7:     {
  8:         if (Function != null)
  9:         {
 10:             return true;
 11:         }
 12: 
 13:         return false;
 14:     }
 15: 
 16: 
 17:     public void Execute(object parameter)
 18:     {
 19:         if (Function != null)
 20:         {
 21:             String str = parameter as String;
 22: 
 23:             Function(str);
 24:         }
 25:     }
 26: 
 27:     public event EventHandler CanExecuteChanged
 28:     {
 29:         add { CommandManager.RequerySuggested += value; }
 30:         remove { CommandManager.RequerySuggested -= value; }
 31:     }
 32: }
 33: 

Here is our XAML file to pass parameter in the binding method.

  1: <Button Grid.Column="0" Grid.Row="2" Margin="5" 
  2: 	Content="GCD" Command="{Binding CalculateCommand}" CommandParameter="GCD"/>
  3: <Button Grid.Column="1" Grid.Row="2" Margin="5" 
  4: 	Content="LCM" Command="{Binding CalculateCommand}" CommandParameter="LCM"/>        
  5: 

Now “GCD” will pass as a parameter when first button click and “LCM” will pass when second button clicks. Here is our binding method that calls two different methods depends on its parameter.

  1: private int Command(String parameter)
  2: {
  3:     int x = nos.FirstNo;
  4:     int y = nos.SecondNo;
  5: 
  6:     if (parameter == "GCD")
  7:     {
  8:         int gcd =  CalculateGCD(x, y);
  9:         MessageBox.Show(gcd.ToString(), "GCD");
 10:         return gcd;
 11:     }
 12:     else if (parameter == "LCM")
 13:     {
 14:         int lcm = CalculateLCM(x, y);
 15:         MessageBox.Show(lcm.ToString(), "LCM");
 16:         return lcm;
 17:     }
 18:     else
 19:         return 0;
 20: }
 21: 

Here is complete XAML code of the program.

  1: <Window x:Class="WpfCommandBinding.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     Title="Command Binding" Height="200" Width="300">
  5:     <Grid Name="grid" Background="Wheat">
  6:         <Grid.ColumnDefinitions>
  7:             <ColumnDefinition/>
  8:             <ColumnDefinition/>
  9:         </Grid.ColumnDefinitions>
 10:         <Grid.RowDefinitions>
 11:             <RowDefinition/>
 12:             <RowDefinition/>
 13:             <RowDefinition/>
 14:         </Grid.RowDefinitions>
 15:         <TextBlock Grid.Column="0" Grid.Row="0" Margin="5"
 16:                    VerticalAlignment="Center" Text="Enter first number"/>
 17:         <TextBox Grid.Column="1" Grid.Row="0" Margin="5" Name="txtFirstNo"
 18:                  VerticalAlignment="Center" Text="{Binding Path=FirstNo}"/>
 19:         <TextBlock Grid.Column="0" Grid.Row="1" Margin="5"
 20:                    VerticalAlignment="Center" Text="Enter second number"/>
 21:         <TextBox Grid.Column="1" Grid.Row="1" Margin="5" Name="txtSecondNo"
 22:                    VerticalAlignment="Center" Text="{Binding Path=SecondNo}"/>
 23:         <Button Grid.Column="0" Grid.Row="2" Margin="5" 
 24:                 Content="GCD" Command="{Binding CalculateCommand}" CommandParameter="GCD"/>
 25:         <Button Grid.Column="1" Grid.Row="2" Margin="5" 
 26:                 Content="LCM" Command="{Binding CalculateCommand}" CommandParameter="LCM"/>        
 27:     </Grid>
 28: </Window>
 29: 

And here is complete C# code of the program.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: using System.ComponentModel;
 15: 
 16: namespace WpfCommandBinding
 17: {
 18:     /// <summary>
 19:     /// Interaction logic for Window1.xaml
 20:     /// </summary>
 21:     public partial class Window1 : Window
 22:     {
 23:         private Numbers nos = new Numbers();
 24: 
 25:         public Window1()
 26:         {
 27:             InitializeComponent();
 28:             MyCommand command = new MyCommand();
 29:             command.Function = Command;
 30:             nos.CalculateCommand = command;
 31: 
 32:             grid.DataContext = nos;
 33:         }
 34: 
 35:         private int Command(String parameter)
 36:         {
 37:             int x = nos.FirstNo;
 38:             int y = nos.SecondNo;
 39: 
 40:             if (parameter == "GCD")
 41:             {
 42:                 int gcd =  CalculateGCD(x, y);
 43:                 MessageBox.Show(gcd.ToString(), "GCD");
 44:                 return gcd;
 45:             }
 46:             else if (parameter == "LCM")
 47:             {
 48:                 int lcm = CalculateLCM(x, y);
 49:                 MessageBox.Show(lcm.ToString(), "LCM");
 50:                 return lcm;
 51:             }
 52:             else
 53:                 return 0;
 54:         }
 55: 
 56:         private int CalculateGCD(int x, int y)
 57:         {
 58:             if (x == 0)
 59:                 return 0;
 60: 
 61:             while (y != 0)
 62:             {
 63:                 if (x > y)
 64:                     x = x - y;
 65:                 else
 66:                     y = y - x;
 67:             }
 68: 
 69:             return x;
 70:         }
 71: 
 72:         private int CalculateLCM(int x, int y)
 73:         {
 74:             int lcm = x * y / CalculateGCD(x, y);
 75:             return x * y / lcm;
 76:         }
 77:     }
 78: 
 79:     public class MyCommand : ICommand
 80:     {
 81:         public Func<String, int> Function
 82:         { get; set; }
 83: 
 84:         public bool CanExecute(object parameter)
 85:         {
 86:             if (Function != null)
 87:             {
 88:                 return true;
 89:             }
 90: 
 91:             return false;
 92:         }
 93: 
 94: 
 95:         public void Execute(object parameter)
 96:         {
 97:             if (Function != null)
 98:             {
 99:                 String str = parameter as String;
100: 
101:                 Function(str);
102:             }
103:         }
104: 
105:         public event EventHandler CanExecuteChanged
106:         {
107:             add { CommandManager.RequerySuggested += value; }
108:             remove { CommandManager.RequerySuggested -= value; }
109:         }
110:     }
111: 
112:     public class Numbers
113:     {
114:         public int FirstNo
115:         { get; set; }
116: 
117:         public int SecondNo
118:         { get; set; }
119: 
120:         public ICommand CalculateCommand
121:         { get; set; }
122:     }
123: }
124: 

The output of this program is same as previous one. Here is the output of this program.

CommandBinding

About these ads

Responses

  1. [...] XAML, Data Binding, Command Binding, ICommand, INotifyPropertyChanged, MVVM, Command « Command Binding with Parameter Passing MVVM Patterns using Dependency Property [...]

  2. [...] Routed Commands We have already seen example of implementing ICommand interface here and here. WPF already define one class which already implement ICommand interface. That class is [...]

  3. HI,
    I need to pass the button content as a parameter. IN the above example the parameter is passed with a string value. Is there any other way by which i can pass the content of button as command parameter. Thanks in advance.

    • The quickest answer i can think of is using MVVM and bind the content of button with your ViewModel and use the same property to pass as a command line argument. Can you please further explain your requirement?

    • Thanks to Wodahs. He proposed the follownig solution.

      <Button Command="{Binding Path=MyCommand}"
      CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Content}">
      Cancel
      </Button>

  4. Found best multi event command binder in codeplex

    Multi Event Command

    Benefits:

    1:Ability to bind multiple event to multiple commands.
    2:In CommandArgs in command handler you can even get original event args this was not possible with existing command binders.
    3:In CommandArgs in command handler you can even get original source of the event this was not possible with existing command binders.
    4:In this you can control individual CanExecute methods.

    Blogs
    Multi Event Command BlogSpot
    Multi Event Command WordPress

    • Thanks for your link. I will take a look at your project shortly. At first it looks an interesting use of Attached Dependency Property.

      Regards
      Zeeshan Amjad


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

Follow

Get every new post delivered to your Inbox.

Join 524 other followers

%d bloggers like this: