WPF MVVM学习

2021-04-02 02:24

阅读:694

但是在考虑了所有情况之后,让我们逻辑地思考下“什么是一个动作?”。它是一个事件,可以由用户从鼠标点击(左键或右键),按钮点击,菜单点击,功能键按下等。所以应该有一种方式通用化这些动作,并且让各种 ViewModel 有一种更通用的方法去绑定它。

逻辑上讲,如果你认为任务动作是一些方法和函数的封装逻辑。那有什么是“方法”和“函数”的通用表达方式呢?......努力想想.......再想想.......“委托”,“委托”,没错,还是“委托”。

我们需要两个委托,一个给“CanExecute”,另一个给“Execute”。“CanExecute”返回一个布尔值用来验证以及根据验证来使能(Enable)或者禁用(Disable)用户界面。“Execute”委托则将在“CanExecute”委托返回 true 时执行。

public class ButtonCommand : ICommand
    {
        public bool CanExecute(object parameter) // Validations
        {
        }
        public void Execute(object parameter) // Executions
        {
        }
    }

因此,换句话说,我们需要两个委托,一个返回布尔值,另一个执行动作并返回空。所以,创建一个“Func”和一个“Action”如何?“Func”和“Action”都可以用来创建委托。

通过使用委托的方法,我们试着创建一个通用的 command 类。我们对 command 类做了三个修改(代码参见下面),同时我也标注了三点 Point 1,2 和 3。

Point1: 我们在构造函数中移除了 ViewModel 对象,改为接受两个委托,一个是“Func”,另一个是“Action”。“Func”委托用作验证(例如验证何时动作将被执行),而“Action”委托用来执行动作。两个委托都是通过构造函数参数传递进来,并赋值给类内部的对应私有成员变量。

Point2 和 3: Func 委托(WhentoExecute)被“CanExecute”调用,执行动作的委托 Whattoexecute 则是在“Execute”中被调用。

public class ButtonCommand : ICommand
{
private Action WhattoExecute;
private Funcbool> WhentoExecute;
        public ButtonCommand(Action What , Funcbool> When) // Point 1
        {
            WhattoExecute = What;
            WhentoExecute = When;
        }
public bool CanExecute(object parameter)
        {
            return WhentoExecute(); // Point 2
        }
public void Execute(object parameter)
        {
            WhattoExecute(); // Point 3
        }
}

在 Model 类中我们已经知道要执行什么了(例如“CalculateTax”),我们也创建一个简单的函数“IsValid”来验证“Customer”类是否有效。

public class Customer
    {
public void CalculateTax()
        {
if (_Amount > 2000)
            {
                _Tax = 20;
            }
else if (_Amount > 1000)
            {
                _Tax = 10;
            }
else
            {
                _Tax = 5;
            }
        }

public bool IsValid()
        {
if (_Amount == 0)
            {
return false;
            }
else
            {
return true;
            }
        }
    }

在 ViewModel 类中我们同时传递函数和方法给 command 类的构造函数,一个给“Func”,一个给“Action”。

public class CustomerViewModel : INotifyPropertyChanged
{
private Customer obj = new Customer();
privateButtonCommandobjCommand;
publicCustomerViewModel()
        {
objCommand = new ButtonCommand(obj.CalculateTax,
obj.IsValid);
        }
}

这样使得框架更好,更解耦, 使得这个 command 类可以以一个通用的方式被其它 ViewModel 引用。下面是改善后的架构, 需要注意 ViewModel 如何通过委托(Func和Action)和 command 类交互。

技术分享图片

 
 

第五步:利用 PRISM

最后如果有一个框架能帮助实现我们的 MVVM 代码那就更好了。PRISM 就是其中一个可复用的框架。PRISM 的主要用途是为了提供模块化开发,但是它提供了一个很好的“DelegateCommand”类拿来代替我们自己创建的 command 类。

所以,第一件事情就是从这里下载 PRISM,编译这个解决方案,添加“Microsoft.Practices.Prism.Mvvm.dll”和“Microsoft.Practices.Prism.SharedInterfaces.dll”这两个 DLL 库的引用。

你可以去掉自定义的 command 类,导入“Microsoft.Practices.Prism.Commands”名称空间, 然后以下面代码的方式使用 DelegateCommand。

public class CustomerViewModel : INotifyPropertyChanged
{
private Customer obj = new Customer();
private DelegateCommand  objCommand;
public CustomerViewModel()
        {
objCommand = new DelegateCommand(obj.CalculateTax,
                                        obj.IsValid);
        }
…………
…………
…………
…………

}    
}

 


评论


亲,登录后才可以留言!