WPF have very powerful concept command binding. We can not only bind the data but also the commands in WPF. And with command binding and data binding we can implement very powerful and reusable design commonly known as MVVM (Model View ViewModel). Before going to discuss the MVVM lets complete our ground work and study the command binding.
The basic concept of command binding is to implement ICommand interface. There are two methods and one events in this interface and we have to implements all of them to create its class. Here is our implementation of our ICommand interface that takes one method without any parameter but return boolean.
1: public class MyCommand : ICommand2: {3: public Func<int> Function4: { 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: public void Execute(object parameter)17: {18: if (Function != null)19: {20: Function();21: }22: }23:24: public event EventHandler CanExecuteChanged25: {26: add { CommandManager.RequerySuggested += value; }27: remove { CommandManager.RequerySuggested -= value; }28: }29: }30:We create one more class to store the information. We also implement the INotifyPropertyChanged interface so whenever there is any change in the interface then the properties update accordingly. Here is our class of number.
1: public class Numbers : INotifyPropertyChanged2: {3: private int _firstNo;4: private int _secondNo;5:6: public int FirstNo7: {8: get9: {10: return _firstNo;11: }12:13: set14: {15: _firstNo = value;16: OnPropertyChanged("FirstNo");17: }18: }19:20: public int SecondNo21: {22: get23: {24: return _secondNo;25: }26:27: set28: {29: _secondNo = value;30: OnPropertyChanged("SecondNo");31: }32: }33:34: public ICommand CalculateGCD35: { get; set; }36:37: public ICommand CalculateLCM38: { get; set; }39:40: public event PropertyChangedEventHandler PropertyChanged;41:42: private void OnPropertyChanged(string propertyName)43: {44: if (this.PropertyChanged != null)45: {46: this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));47: }48: }49: }50:We create two objects of our command objects and set the methods with our handler. Here is a piece of code to do this.
1: MyCommand command1 = new MyCommand();2: command1.Function = CalculateGCD;3: nos.CalculateGCD = command1;4:5: MyCommand command2 = new MyCommand();6: command2.Function = CalculateLCM;7: nos.CalculateLCM = command2;8:Now we can do a binding with command. Here is a piece of XAML code to do command binding.
1: <Button Grid.Column="0" Grid.Row="2" Margin="5"2: Content="GCD" Command="{Binding CalculateGCD}"/>3: <Button Grid.Column="1" Grid.Row="2" Margin="5"4: Content="LCD" Command="{Binding CalculateLCM}"/>Now if we click the first button then it will execute the CalculateGCD method and if we click on the second button it will execute the CalculateLCM method. 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 CalculateGCD}"/>25: <Button Grid.Column="1" Grid.Row="2" Margin="5"26: Content="LCM" Command="{Binding CalculateLCM}"/>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 WpfCommandBinding17: {18: /// <summary>19: /// Interaction logic for Window1.xaml20: /// </summary>21: public partial class Window1 : Window22: {23: private Numbers nos = new Numbers();24:25: public Window1()26: {27: InitializeComponent();28: MyCommand command1 = new MyCommand();29: command1.Function = CalculateGCD;30: nos.CalculateGCD = command1;31:32: MyCommand command2 = new MyCommand();33: command2.Function = CalculateLCM;34: nos.CalculateLCM = command2;35:36: grid.DataContext = nos;37: }38:39: private int CalculateGCDInternal(int x, int y)40: {41: if (x == 0)42: return 0;43:44: while (y != 0)45: {46: if (x > y)47: x = x - y;48: else49: y = y - x;50: }51:52: return x;53: }54:55: private int CalculateGCD()56: {57: int x = nos.FirstNo;58: int y = nos.SecondNo;59:60: int gcd = CalculateGCDInternal(x, y);61: MessageBox.Show(gcd.ToString(), "GCD");62: return gcd;63: }64:65: private int CalculateLCM()66: {67: int x = nos.FirstNo;68: int y = nos.SecondNo;69: int lcm = x * y / CalculateGCDInternal(x, y);70: MessageBox.Show(lcm.ToString(), "LCM");71: return x * y / lcm;72: }73: }74:75: public class MyCommand : ICommand76: {77: public Func<int> Function78: { get; set; }79:80: public bool CanExecute(object parameter)81: {82: if (Function != null)83: {84: return true;85: }86:87: return false;88: }89:90: public void Execute(object parameter)91: {92: if (Function != null)93: {94: Function();95: }96: }97:98: public event EventHandler CanExecuteChanged99: {100: add { CommandManager.RequerySuggested += value; }101: remove { CommandManager.RequerySuggested -= value; }102: }103: }104:105: public class Numbers : INotifyPropertyChanged106: {107: private int _firstNo;108: private int _secondNo;109:110: public int FirstNo111: {112: get113: {114: return _firstNo;115: }116:117: set118: {119: _firstNo = value;120: OnPropertyChanged("FirstNo");121: }122: }123:124: public int SecondNo125: {126: get127: {128: return _secondNo;129: }130:131: set132: {133: _secondNo = value;134: OnPropertyChanged("SecondNo");135: }136: }137:138: public ICommand CalculateGCD139: { get; set; }140:141: public ICommand CalculateLCM142: { get; set; }143:144: public event PropertyChangedEventHandler PropertyChanged;145:146: private void OnPropertyChanged(string propertyName)147: {148: if (this.PropertyChanged != null)149: {150: this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));151: }152: }153: }154: }155:
Here is the output of the program.


[...] to MVVM We already saw the example of command binding here and here. In fact that was the first step towards the MVVM (Model, View, ViewModel). In that [...]
By: Introduction to MVVM « Zeeshan Amjad's WPF Blog on January 22, 2010
at 11:08 pm
[...] 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 [...]
By: Command Binding with Parameter Passing « Zeeshan Amjad's WPF Blog on January 22, 2010
at 11:09 pm
[...] 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 [...]
By: Creating Routed Commands « Zeeshan Amjad's WPF Blog on February 11, 2010
at 11:30 pm
Very very helpful. But please appropriate formate the code. Use code snippet. It will increase readability. I’m waiting….
By: Towhid on March 21, 2011
at 8:05 am
Thanks to like it. I was using Windows Live Writer with one code formatting plug in to write the code. I will take a look at this and will update the code formatting if i will come across any otehr good code formatting plug in.
Regards
Zeeshan Amjad
By: zamjad on March 21, 2011
at 9:08 am
Hello Zeeshan.
Thanking for sharing your Knowledge which really helps us a lot .
i have tried the above Article and had a problem to compile the code,which was providing me an error for the line No:23
private Numbers nos = new Numbers();
Error:The type or namespace name ‘Numbers’ could not be found (are you missing a using directive or an assembly reference
am i missing any namespace to be added for the above line of code.
Could you please help me with this. If you can help me please email me.
Thank you in advance.
By: shardha on April 4, 2011
at 3:06 pm
Thanks to like it.
I created a Number class in the same file. Make sure you have that class. If you created that class in another namespace, please include the referenfce of that namespace.
Regards
Zeeshan Amjad
By: zamjad on April 12, 2011
at 9:44 am
Could you please upload the project (in .zip or .rar format)?
Excellent blog!
By: Towhid on November 13, 2011
at 12:50 am
Thanks to like my blog. I couldn’t find a way to upload project file at wordpress. I am thinking to upload the project at skydrive and post a link here.
Thanks to like my blog and visit here.
Regards
Zeeshan Amjad
By: Zeeshan Amjad on November 21, 2011
at 5:19 pm
hey there can u pls tell me where to start. seriously i have to backtrack your dates of upload, to get how to start to learn wpf. and thanks for such good blog.
By: here on December 3, 2012
at 1:11 pm
i just want to learn wpf with mvvm.
By: here on December 3, 2012
at 1:13 pm
Thanks to like my blog. This blog is not a replacement of any book, but can be used as a supplement with any good WPF book. Most of the articles in this blogs are actually some problems faced by some of my friends, myself or posted on WPF or any other forum, there are very few real tutorial here.
For MVVM, different people will understand it in different way and it is better to revisit the topics again to understand those points which you miss in first go.
As far a my blog is concern, I guess this would be a good starting point for you to give some historical background.
Evaluation of MVVM
http://zamjad.wordpress.com/2010/02/07/evaluation-of-mvvm/
Then take a look at this very small example of MVVM
Introduction to MVVM
http://zamjad.wordpress.com/2010/01/21/introduction-to-mvvm/
Then see more useful implementation of ICommand interface
Implementing ICommand interface
http://zamjad.wordpress.com/2011/08/04/implement-icommand-interface/
Then it would be nice to define base class for ViewModel
Define base class for ViewModel
http://zamjad.wordpress.com/2011/03/14/define-base-class-for-modelview/
and
http://zamjad.wordpress.com/2011/05/25/define-base-class-for-viewmodel-revisited/
This is one small trick to handle event in ViewModel epically close event
Implement Close Window Functionality in ViewModel
http://zamjad.wordpress.com/2011/03/09/implement-close-window-functionality-in-viewmodel/
This is more general approach to convert event into command
Convert Event into Command in MVVM Model
http://zamjad.wordpress.com/2011/06/07/convert-event-into-command-in-mvvm-model/
and here is more general approach
http://zamjad.wordpress.com/2011/08/08/convert-event-into-command-in-mvvm-model-revisited/
Then I recommend to take a look at mediator design pattern series. Although it is written UserControl, but same is valid for ViewModel
http://zamjad.wordpress.com/2012/01/05/using-mediator-to-communicate-between-user-controls-part-1/
http://zamjad.wordpress.com/2012/01/06/using-mediator-to-communicate-between-user-controls-part-2/
http://zamjad.wordpress.com/2012/01/08/using-mediator-to-communicate-between-user-controls-part-3/
http://zamjad.wordpress.com/2012/01/09/using-mediator-to-communicate-between-user-controls-part-4/
http://zamjad.wordpress.com/2012/01/11/using-mediator-to-communicate-between-user-controls-part-5/
http://zamjad.wordpress.com/2012/02/22/using-mediator-to-communicate-between-user-controls-part-6/
http://zamjad.wordpress.com/2012/03/05/using-mediator-to-communicate-between-user-controls-part-7/
Hope it would give you a better understanding of MVVM and its usage.
Again thanks a lot to visit and like my blog.
Regards
Zeeshan Amjad
By: Zeeshan Amjad on December 4, 2012
at 11:33 am