WPF之MVVM(Step2)——自己实现DelegateCommand:ICommand

在自己实现MVVM时,上一篇的实现方式基本是不用,因其对于命令的处理不够方便,没写一个命令都需要另加一个Command的类。此篇主要介绍DelegateCommand来解决上面所遇到的问题。

首先,我们创建自己的DelegateCommand。

代码如下:

 /// <summary>
    /// 实现DelegateCommand
    /// </summary>
    class MyDelegateCommand : ICommand
    {
        /// <summary>
        /// 命令所需执行的事件
        /// </summary>
        public Action<object> ExecuteCommand { get; set; }
        /// <summary>
        /// 命令是否可用所执行的事件
        /// </summary>
        public Func<object, bool> CanExecuteCommand { get; set; }

        public MyDelegateCommand()
        {
        }

        public MyDelegateCommand(Action<object> execute, Func<object, bool> canexecute)
        {
            ExecuteCommand = execute;
            CanExecuteCommand = canexecute;
        }

        /// <summary>
        /// 命令可用性获取
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            return CanExecuteCommand(parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        /// <summary>
        /// 命令具体执行
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            ExecuteCommand(parameter);
        }
    }

 

其中的重点是利用两个委托,将方法的实现分离出去,接下来看我们的ViewModel:

  class TestViewModel : INotifyPropertyChanged
    {

        private string teststr;
        /// <summary>
        /// 待通知字符串
        /// </summary>
        public string TestStr
        {
            get { return teststr; }
            set
            {
                teststr = value;
                RaiseChanged("TestStr");
            }
        }

        /// <summary>
        /// 测试命令
        /// </summary>
        public ICommand TestCommand { get; set; }


        public TestViewModel()
        {
            TestCommand = new MyDelegateCommand();
            (TestCommand as MyDelegateCommand).ExecuteCommand = Test;
            (TestCommand as MyDelegateCommand).CanExecuteCommand = CanTest;
            //or
            //TestCommand = new MyDelegateCommand(Test, CanTest);
        }

        int i = 0;
        /// <summary>
        /// testcommand执行的方法
        /// </summary>
        /// <param name="para"></param>
        private void Test(object para)
        {
            i++;
            TestStr = i.ToString();
        }
        /// <summary>
        /// testcommand是否可用
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        private bool CanTest(object para)
        {
            return true;
        }

        #region INotifyPropertyChanged接口实现
        public void RaiseChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

其中的Test,CanTest就是之前写在Command中的实现,通过此实现,我们可以将界面呈现逻辑全部集中到ViewModel中。

其界面还是一样使用上一篇的。

 


项目代码托管地址:https://wpfmvvm.codeplex.com/

WPF之MVVM(Step2)——自己实现DelegateCommand:ICommand

上一篇:10.C#匿名函数的变量捕获(五章5.5)


下一篇:我对于 setWindow, setViewPort 与 translate 的理解