在自己实现MVVM时,上一篇的实现方式基本是不用,因其对于命令的处理不够方便,没写一个命令都需要另加一个Command的类。此篇主要介绍DelegateCommand来解决上面所遇到的问题。
首先,我们创建自己的DelegateCommand。
代码如下:
class="brush: csharp; auto-links: true; collapse: true; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"> /// <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中。
其界面还是一样使用上一篇的。