Monday, October 28, 2013

ICommand Implementation in Silverlight / WPF

In this article I am going to describe how to implement ICommands, which work for projects that use MVVM (Model View View-Model). The approach I am describing works in silverlight or WPF.

Its for more advanced than DelegateCommand which is offered by silverlight.


To Implement ICommand, first have to create class which implements ICommand, let its be CommonCommand


1.   public class CommonCommand : ICommand

    {
           public event EventHandler CanExecuteChanged;

        public virtual void Execute(object parameter)

        {
            if (CanExecuteChanged != null)
                 CanExecuteChanged(this, new EventArgs());
        }

        public virtual bool CanExecute(object parameter)

        {
            return true;
        }
    }

        above class is normal implementation of ICommand, which is not generic for all purpose, lets make it more generic for usability.


2. To make it more generic we have to use Action and Predicate


  Action: for more details regarding action, take a look in to this Action Delegate Example


Predicate: for more details regarding predicate, take a look into this Predicate Example

After creating Common Command, its look like below,

public class CommonCommand : ICommand
    {
        #region ICommand Implementation

        #region Generic Command Parameter

        private readonly Predicate<object> _canExecute;
        private readonly Action<object> _execute;
        private readonly Action _executeNoParam;

        public CommonCommand(Action action)
        {
            _executeNoParam=action;
        }

        public CommonCommand(Action<object> action)
        {
            _execute = action;
        }

        public CommonCommand(Action<object> action, Predicate<object> canExecute)
            : this(action)
        {
            _canExecute = canExecute;
        }
        public CommonCommand(Action action, Predicate<object> canExecute)
            : this(action)
        {
            _canExecute = canExecute;
        }
     

        #endregion Generic Command Parameter

        #region Command Implementation

        public event EventHandler CanExecuteChanged;

        public virtual bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }
            return _canExecute(parameter);
        }

        public virtual void Execute(object parameter)
        {
            if (_execute != null)
                _execute(parameter);
            else if (_executeNoParam != null)
                _executeNoParam();
        }

        public virtual void Execute()
        {
            if (_executeNoParam != null)
                _executeNoParam();
        }

        protected void OnCanExecuteChanged(object parameter)
        {
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, new EventArgs());
            }
        }

        #endregion

        #endregion ICommand Implementation
    }


3. Using Common Command, to use comman command its quite simple

Example:
//Command
     private ICommand _openFileCommand;

        public ICommand OpenFileCommand
        {
            get
            {
                if (_openFileCommand == null)
                {
                    _openFileCommand = new CommonCommand(OpenDialog);
                }
                return _openFileCommand;
            }
         
        }
//method

  private void OpenDialog()
  {
    //your logic here
 }


4. Advantage:

           for DelegateCommand, you always have to pass object as parameter even if you don't required, but CommonCommand override and it allows you to define your own implementation.

//Normal DelegateCommand

private ICommand _openFileCommand;

        public ICommand OpenFileCommand
        {
            get
            {
                if (_openFileCommand == null)
                {
                    _openFileCommand = new DelegateCommand(OpenDialog);
                }
                return _openFileCommand;
            }
         
        }

//Method
 private void OpenDialog(object obj) // unwanted object as parameter
        {
        }

No comments:

Post a Comment