ICommand Interface in WPF
4.91 /5 ( 48 vote s )
ICommand interface and its use in generic implementation of Command
Introduction
In this article, we will learn about
ICommand
interface and its use in generic implementation of
Command
while working with MVVM (Model View ViewModel) Pattern in WPF/Silverlight applications. First, we will understand about
Command
and then look into members of
ICommand
interface. We will create a demo application in WPF to learn the use of
ICommand
. In the demo application, we will use MVVM Pattern also.
Note : For this article, as a prerequisite, we must have basic understanding of WPF and MVVM pattern. If you are new to MVVM Pattern, please have a look at Wiki and MSDN Page .
Outline
What is Command
In WPF context,
Command
is any class which implement
ICommand
interface. There is minute difference between Commands and Events. Events are defined and associated with UI Controls. But Commands are more abstract and focused on what to be done. One Command can be associated with multiple UI Controls/Options. For example, a Save Command we can be executed on Save Button Click, or by pressing
Ctrl+S
or by choosing
Save
option from
Menu
bar. To have interactions in application, we use either events or commands.
In WPF applications, we have two options to provide interactions in UI:
RoutedEvent
s available in WPF to use for this case.
ViewModel
and invoke that code using Command, if we are following MVVM pattern.
If we are using MVVM Pattern, then generally we should not write code in code-behind files. So we cannot use RoutedEvents because RoutedEvents are not accessible in ViewModels. That is why we have to use Commands to execute desired code block written in ViewModel.
Thus Commands provide glue between View and ViewModel for interactivity.
ICommand Interface
ICommand
is an interface which has three members as shown in the below table:
| Member Of ICommand | Description |
bool CanExecute(object parameter)
|
|
event EventHandler CanExecuteChanged
|
This is used to notify the UI controls associated with
|
void Execute(object parameter)
|
This is the method which does actual work which is intended for the
Why ICommand Interface
To make it easy to understand, let us create a demo application. Overview of Demo Application
The demo application is doing very basic calculation, just to show
The final screenshot of the demo application is as shown below: Creating UI for Demo AppNow fire up Visual Studio and to create demo application, please follow the steps given below: Step 1
Create a WPF application named as
Step 2First, we will create a layout demo UI. To do that, we will create the grid with four rows and four columns. Controls will be placed in this grid by specifying rows and columns position. Write the same code as shown below in CalculatorView.xaml file. <Grid DataContext="{Binding Source={StaticResource calculatorVM}}" Background="#FFCCCC"> <Grid.RowDefinitions> <RowDefinition Height="80"></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition Height="80"></RowDefinition> <RowDefinition Height="44"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" FontSize="25" VerticalAlignment="Top" HorizontalAlignment="Center" Foreground="Blue" Content="ICommand Demo"/> <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="10,0,0,0" VerticalAlignment="Bottom" FontSize="20" Content="First Input"/> <Label Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2" Margin="10,0,0,0" VerticalAlignment="Bottom" FontSize="20" Content="Second Input"/> <TextBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="10,0,0,0" FontSize="20" HorizontalAlignment="Left" Height="30" Width="150" TextAlignment="Center" Text="{Binding FirstValue, Mode=TwoWay}"/> <TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Margin="10,0,0,0" FontSize="20" HorizontalAlignment="Left" Height="30" Width="150" TextAlignment="Center" Text="{Binding SecondValue, Mode=TwoWay}"/> <Rectangle Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Fill="LightBlue"></Rectangle> <Button Grid.Row="2" Grid.Column="0" Content="+" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Width="50" FontSize="30" Command="{Binding AddCommand}"></Button> <Button Grid.Row="2" Grid.Column="1" Content="-" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Width="50" FontSize="30" Command="{Binding SubstractCommand}"></Button> <Button Grid.Row="2" Grid.Column="2" Content="*" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Width="50" FontSize="30" Command="{Binding MultiplyCommand}"></Button> <Button Grid.Row="2" Grid.Column="3" Content="%" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Width="50" FontSize="30" Command="{Binding DivideCommand}"></Button> <Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" FontSize="25" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Content="Result : "/> <TextBlock Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" FontSize="20" Margin="10,0,0,0" Background="BlanchedAlmond" TextAlignment="Center" HorizontalAlignment="Left" Height="36" Width="150" Text="{Binding Output}"/> </Grid>
Now go to
MainWindow.xaml
file, add
Create a tag for CalculatorView.xaml view inside parent grid of MainWindow.xaml . <views:CalculatorView/> </Grid>Step 3
Now we need to attach properties of two textboxes and label in
CalculatorView.xaml
to its
As we can see in XAML, we have bounded UI propertites with
To do Binding with
Property “
How to Use ICommand Interface
To bind Commands with UI Controls, we need to create a
First, we would be creating a
Step 4
We have already created a “
Plus
” button on UI page. As we are following MVVM pattern, in this case to handle such kind of functionality, we need to implement
Step 5
Now create a
Step 6
Register namespace of
After namespaces, add
Step 7
Implement
Step 8
Create a command named as “
Step 9
Now run the application, click on “
Plus
” button,
While execution of
Put the breakpoint to
Need of INotifyPropertyChanged
The purpose of
Step 10
As we have seen in the above step, “
So let us implement
Step 11
Inherit
Now run the application, we would be able to perform
Problem with Individual CommandsAs of now, we need to create separate command classes for each operation. As we have done, for PlusCommand class, it has the following drawbacks:
First
:
Second
: From
Third
: As we cannot reuse
That’s why we create a generic command class to handle all kind of operations. For that, we can use inbuilt delegates. Generic Implementation of Command
There are many inbuilt delegates like
Step 12
In the above steps, we have created four command classes to handle four button click event. Now by using
Now we need to change one line of code. Comment the first line and uncomment the second line of
Before returning from this
Put the breakpoint on constructor of
Now all four operations can be handled just by using
Conclusion |