Search code examples
windows-8winrt-xaml

Any WinRT iCommand/CommandBinding implementaiton samples out there?


Abstracting commands into the View Model is a valuable practice with XAML/MVVM projects. I get that. And, I see ICommand in in WinRT; but, how do we implement it? I haven't found a sample that actually works. Anyone know?


Solution

  • My all time favorite has to be the DelegateCommand provided by the Microsoft Patterns and Practices team. It allows you to create a typed command:

    MyCommand = new DelegateCommand<MyEntity>(OnExecute);
    ...
    private void OnExecute(MyEntity entity)
    {...}
    

    It also provides a way to raise the CanExecuteChanged event (to disable/enable the command)

    MyCommand.RaiseCanExecuteChanged();
    

    Here's the code:

    public class DelegateCommand<T> : ICommand
    {
        private readonly Func<T, bool> _canExecuteMethod;
        private readonly Action<T> _executeMethod;
    
        #region Constructors
    
        public DelegateCommand(Action<T> executeMethod)
            : this(executeMethod, null)
        {
        }
    
        public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
        }
    
        #endregion Constructors
    
        #region ICommand Members
    
        public event EventHandler CanExecuteChanged;
    
        bool ICommand.CanExecute(object parameter)
        {
            try
            {
                return CanExecute((T)parameter);
            }
            catch { return false; }
        }
    
        void ICommand.Execute(object parameter)
        {
            Execute((T)parameter);
        }
    
        #endregion ICommand Members
    
        #region Public Methods
    
        public bool CanExecute(T parameter)
        {
            return ((_canExecuteMethod == null) || _canExecuteMethod(parameter));
        }
    
        public void Execute(T parameter)
        {
            if (_executeMethod != null)
            {
                _executeMethod(parameter);
            }
        }
    
        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged(EventArgs.Empty);
        }
    
        #endregion Public Methods
    
        #region Protected Methods
    
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    
        #endregion Protected Methods
    }