WPF ICommand in MVVM

Prabhat39
Posted by in WPF category on for Intermediate level | Points: 250 | Views : 42742 red flag

This article explain ICommand and its member in detail in MVVM architecture.


 Download source code for WPF ICommand in MVVM

WPF ICommand in MVVM

Introduction

Commands provide a mechanism for the view to update the model in MVVM architecture. Commands provide a way to search the element tree for a command handler. ICommand interface is defined inside System.Windows.Input namespace. It is having two methods and an event.

bool CanExecute(object parameter);

void Execute(object parameter);

event EventHandler CanExecuteChanged;

 

Execute method only invoked when CanExecute return true. In case CanExecute method return false then the binding control disable automatically.

In order to know CanExecute value listen to CanExecuteChanged event, that may vary based on parameter passed.

Objective

To undertand ICommand interface and it's use in detail with MVVM architecture.

Using Code

Use of ICommand

ICommand interface is generally used in MVVM architecture. Here in Button control Command property is bind with “UpdateCommand”. As UpdateCommand is nothing but ICommand instance, so while loading window it will check for CanExecute return value and if it return true it will make button control enable and Execute method ready to use otherwise button control get disable.

<Button x:Name="btnUpdate" Width="100" Height="20" HorizontalAlignment="Center" Grid.Row="1" Content="Update" Command="{Binding Path=UpdateCommand}"/>

 

Passing parameter to CanExecute and Execute method

Parameter can be passed through “CommandParameter” property. Once button clicked then the selected address value passed to the ICommand.Execute method.

The CommandParameter is sent to both CanExecute and Execute events.

<Button x:Name="btnUpdate" Width="100" Height="20" HorizontalAlignment="Center" Grid.Row="1" Content="Update" Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=lstPerson, Path=SelectedItem.Address}"></Button>


Tasks of CanExecuteChanged

CanExecuteChanged notifies any command sources (like a Button or CheckBox) that are bound to that ICommand that the value returned by CanExecute has changed. Command sources care about this because they generally need to update their status accordingly (eg. a Button will disable itself if CanExecute() returns false).

Listen CanExecuteChanged

The CommandManager.RequerySuggested event is raised whenever the CommandManager thinks that something has changed that will affect the ability of commands to execute. This might be a change of focus, for example. Turns out that this event fires a lot.

      public event EventHandler CanExecuteChanged

        {

            add { CommandManager.RequerySuggested += value; }

            remove { CommandManager.RequerySuggested -= value; }

        }  

 

ICommand in MVVM

UI





Model 

Create a folder named as Model and a class named as Person. Implement INotifyPropertyChanged and override PropertyChanged event. Defined two properties Name and Address.

    public class Person : INotifyPropertyChanged

    {

        private string name;

        private string address;

 

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

 

        public string Name

        {

            get

            {

                return name;

            }

            set

            {

                name = value;

                OnPropertyChanged("Name");

            }

        }

        public string Address

        {

            get

            {

                return address;

            }

            set

            {

                address = value;

                OnPropertyChanged("Address");

            }

        }

    }

ViewModel

Create a folder named as ViewModel and a class named as PersonViewModel. Initialize a List object of type person. Expose this object through Persons property. Also expose ICommand instance in this class.

Define a class Updater and implement ICommand interface.

public class PersonViewModel

    {

        private IList<Person> _personList;

        public PersonViewModel()

        {

            _personList = new List<Person>()

            {

                new Person(){Name="Prabhat", Address="Bangalore"},

                new Person(){Name="John",Address="Delhi"}

            };

        }

        public IList<Person> Persons

        {

            get { return _personList; }

            set { _personList = value; }

        }

        private ICommand mUpdater;

        public ICommand UpdateCommand

        {

            get

            {

                if (mUpdater == null)

                    mUpdater = new Updater();

                return mUpdater;

            }

            set

            {

                mUpdater = value;

            }

        }

    }

    class Updater : ICommand

    {

        #region ICommand Members

 

        public bool CanExecute(object parameter)

        {

            return true;

        }

 

        public event EventHandler CanExecuteChanged

        {

            add { CommandManager.RequerySuggested += value; }

            remove { CommandManager.RequerySuggested -= value; }

        }

 

        public void Execute(object parameter)

        {

            //Your Code

        }

 

        #endregion

    }

View

Create a view folder and a Person.xaml class. Bind command to the button control. Once button is clicked, command parameter passed to the Execute method. You can also bind command to any control support command property. TextBox is bind with listView selectedItem.

 <Grid>

        <Grid.RowDefinitions>

            <RowDefinition Height="auto"/>

            <RowDefinition Height="auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="100"></ColumnDefinition>

                <ColumnDefinition Width="*"></ColumnDefinition>

            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>

                <RowDefinition Height="auto"></RowDefinition>

                <RowDefinition Height="auto"></RowDefinition>

            </Grid.RowDefinitions>

            <Label x:Name="lblName" Content="Name" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"></Label>

            <TextBox x:Name="txtName" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" Text="{Binding ElementName=lstPerson, Path=SelectedItem.Name}"></TextBox>

            <Label x:Name="lblAddress" Content="Address" Grid.Row="1" Grid.Column="0" VerticalAlignment="Top"></Label>

            <TextBox x:Name="txtAddress" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" Text="{Binding ElementName=lstPerson, Path=SelectedItem.Address}"></TextBox>

        </Grid>

        <Button x:Name="btnUpdate" Width="100" Height="20" HorizontalAlignment="Center" Grid.Row="1" Content="Update"

                Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=lstPerson, Path=SelectedItem.Address}"></Button>

        <ListView x:Name="lstPerson" Grid.Row="2" ItemsSource="{Binding Persons}">

            <ListView.View>

                <GridView>

                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />

                    <GridViewColumn Header="Address" Width="200" DisplayMemberBinding="{Binding Address}"/>

                </GridView>

            </ListView.View>

        </ListView>

    </Grid>

  

 

 

App.xaml.cs

 

Override OnStartup method of Application class. Initialize view and viewModel class and wrap viewmodel to view by DataContext property.

 

protected override void OnStartup(StartupEventArgs e)

{

            base.OnStartup(e);

            View.Person person = new View.Person();

            PersonViewModel personViewModel = new PersonViewModel();

            person.DataContext = personViewModel;

            person.Show();

}

 

Summary

1.       What is ICommand in WPF.

2.       How ICommand used in MVVM architecture.

3.       MVVM architecture flow.

4.       How to pass parameter in CanExecute and Execute method.

5.       How to listen to CanExecuteChanged event.

Point Of Interest

Instead of events, commands have been used in MVVM architecture. We cannot pass parameters to the event but we can pass parameters through command.

 

Page copy protected against web site content infringement by Copyscape

About the Author

Prabhat39
Full Name: Prabhat Kumar
Member Level:
Member Status: Member
Member Since: 12/21/2012 5:30:10 AM
Country: India
Regards, Prabhat Kumar
http://www.dotnetfunda.com
Prabhat is a programmer and having 5+ years of developing experience in IT field. Major strength are C#, WPF, asp.net and SQL server 2008. He is also having good exposure in WCF.

Login to vote for this post.

Comments or Responses

Posted by: satprince99-27953 on: 8/10/2014 | Points: 25
hi,

I am getting error as can't find resource in Person.xaml file for above example. can u please help me on this..

Login to post response

Comment using Facebook(Author doesn't get notification)