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

时间:2023-03-08 21:39:35

在自己实现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/