[译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)

原文:[译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)

  应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等。接下来我们加上一些像按钮这样的UI元素来看MVVM类怎么演变的。与之前的UI相比,这次我们加上一个"Cal Tax"按钮,当我们点击这个依赖于“sales amount”的按钮时,它会计算税费并显示在同窗口内。

  为了完成所述的功能,我们先在Model类中添加一个CalculateTax的方法。当这个方法被调用时,它根据工资范围来计算税费并把它储存在Tax这个属性中。

public class Customer
    {

        ...

        private double _Tax;

        public double Tax => _Tax;

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

  因为view model是model类的包装,我们需要在view model中创建一个方法来调用model的Calculate方法。

public void Calculate()
        {....
            obj.CalculateTax();
        }

  现在我们希望从界面上调用Calculate方法时使用XAML而不是后台代码。现在还不能在XAML中直接调用Calculate方法,这时我们需要用到WPF command类。

  如果你想用属性来传递数据到view model 我们需要用到bindings,如果你想要从view传递actions我们需要用到commands.  

  所有属于view的actions都被传递到command类,因此第一步就是创建command类。为了创建一个这样的command类我们需要像下面这样实现ICommand接口。

  有2个方法我们必须要实现,CanExecute和Execute。在Execute方法中,我们写当这个action发生时我们真的要执行的逻辑。在CanExecute方法中,我们写一些验证代码来确定我们的Execute方法是否应该被执行。

 public class ButtonCommand:ICommand
    {
        public bool CanExecute(object parameter)
        {
            //验证代码
        }

        public void Execute(object parameter)
        {
            //执行逻辑
        }

        public event EventHandler CanExecuteChanged;
    }

  现在所有的actions调用时先来到command类然后再路由到view model 类。换句话说就是command类需要覆盖view model类。

  下面是一些简短的代码摘要。有4个重要的点需要记下来:

  1. 创建的view model对象是私有成员级别的对象。
  2. 这个对象将view model通过构造函数来传递。
  3. 暂时我们没有在CanExecute中添加验证代码,它永远返回true.
  4. 在Execute方法中我们调用了view model类的Calculate方法。
public class ButtonCommand:ICommand
    {
        private CustomerViewModel _obj;

        public ButtonCommand(CustomerViewModel obj)
        {
            _obj = obj;
        }
        public bool CanExecute(object parameter)
        {
            //验证代码
            return true;
        }

        public void Execute(object parameter)
        {
            //执行逻辑
            _obj.Calculate();
        }

        public event EventHandler CanExecuteChanged;
    }

  在上面的command的代码中,view model对象通过构造函数来传递。因此view model类需要创建一个command对象并通过ICommand接口暴露这个command对象。这个ICommand接口会被利用然后在WPF XAML中调用。一些关于CustomerViewModel类去用command类的重点:

  1. command类是CustomerViewModel类的一个私有成员级别的对象。
  2. 在view model类中,当前实例通过构造函数传递给command类。当我们之前解释command类代码时,我们说command类的构造函数获取到view model类的实例。因此在这一节中,我们把当前实例传递给command类。
  3. command对象以ICommand接口的形式暴露出来,这样它就可以在XAML里面来用了。
 public class CustomerViewModel
{
        private readonly ButtonCommand _objButtonCommandCommand;

        public CustomerViewModel()
        {
            _objButtonCommandCommand=new ButtonCommand(this);
        }

        public ICommand CalClick => _objButtonCommandCommand;.....
}

  在UI上添加一个按钮来让它把按钮的行为和暴露为ICommand的方法关联起来。现在可以打开这个按钮的属性,找到命令属性,然后点击创建数据绑定。

  然后选择static resource然后给按钮加上ButtonCommand。

  当你去点击cal tax的按钮时,它回去执行CalculateTax方法并把tax的值存在_tax变量中。

  换句话中,UI不会自动的被通知关于Tax Cal.因此我们需要传递从对象到UI的某种通知告诉它们tax值已经改变了,然后UI来重新加载新的绑定的数据。

  在View model 勒种,我们需要发送一个通知时间到view上。  

  要在VIEW MODEL类中使用通知我们需要做3件事情。所有的3件事情在下面都标出来了。

  • 像如下代码一样实现INotifyPropertyChanged接口。一旦你实现了这个接口,它就创建了一个PropertyChangedEventHandler的事件对象。
  • 在Calculate方法中用PropertyChanged对象来引发事件,并且在这里面表示哪个属性会被通知。例子中使用的是Tax属性。为了安全起见我们在使用PropertyChanged对象之前先检查它是否为空。
public class CustomerViewModel:INotifyPropertyChanged
{   ....
    public void Calculate()
        {
            obj.CalculateTax();
            OnPropertyChanged(nameof(Tax));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
}

  当你运行这个应用时,你应该可以看到当你点击按钮时Tax的值也发生了变化。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9131390.html

时间: 2024-11-01 14:11:58

[译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)的相关文章

WPF/MVVM模式入门教程(二):实现INotifyPropertyChanged接口

1.创建NotifyPropertyChanged类 我们在common文件夹下创建一个名为NotifyPropertyChanged.cs的类,该类继承INotifyPropertyChanged接口主要用于消息通知,当UI里的值发生改变的时候,能够触发相应的改变. using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text;

WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)

原文:WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码) 之前的改进已经挺棒的,但是我们现在知道了后台代码的问题,那是否可能把后台代码全部去除呢?这时候就该WPF binding 和 commands 来做的事情了. WPF就是以超吊的binding,commans和声明式编程而闻名的.声明式编程意思就是相比于全部用C#代码来写,我们也可以用XAML来表示c#代码.Binding可以帮助我们把2个不同的WPF对象连接起来来发送和接收数据. 你看到

WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击button这样的行为用命令来联系.view model和model在内部通信. 但是在上面的架构中有一个问题,command类和view model有很严重的耦合.如果你记得command类的代码(在下面也有展示),在构造函数中传递view model对象,意味着这个command 类不能再其他的vie

WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)

我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的. 现在,感觉和事实是完全不同的两个东西.当你看到三层架构的框图的时候,你会觉得每层的职责被分配的很好.但是当你你真的去写代码的时候你会发现其实一些层被迫去做本不应该他们做的额外的事情(违反了SOLID原则的S). 这个额外的工作就是在UI-Model和Model-Data access之间的代码.让我们就把这些代码称为“GLUE”代码.有两种主要的逻辑会造成“GLUE”代码(也许我知道的并不够多,其他的可以自己发现): 1

WPF Step By Step 系列-Prism框架在项目中使用

WPF Step By Step 系列-Prism框架在项目中使用 回顾 上一篇,我们介绍了关于控件模板的用法,本节我们将继续说明WPF更加实用的内容,在大型的项目中如何使用Prism框架,并给予Prism框架来构建基础的应用框架,并且如何来设计项目的架构和模块,下面我们就来一步步开始吧. 本文大纲 1.Prism框架下载和说明 2.Prism项目预览及简单介绍. 3.Prism框架如何在项目中使用. Prism框架下载和说明 Prism框架是针对WPF和Silverlight的MVVM框架,这

WPF Step By Step 自定义模板

WPF Step By Step 自定义模板 回顾 上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现的方案和最终的运行效果. 本文大纲 1.控件模板及数据模板 2.ListBox深度定制模板. 3.TreeView高级模板使用实例. 控件模板及数据模板 控件模板 什么是控件模板,指定可以在控件的多个实例之间共享 Control 的可视结构和性能方面的方面.控件模板其实就是我们在可视方面的自定义模板

WPF Step By Step 控件介绍

WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子,希望我们可以对WPF的掌握会更深刻.本文涉及的内容可能较多.请大家慢慢看看.错误之处,还请指出. 本文大纲 1.基本控件介绍与用法. 基本控件介绍与用法 文本控件 Label控件 label控件:一般用户描述性文字显示. 在Label控件使用时,一般给予用户提示.用法上没有什么很特殊的,label

C++开发WPF,Step by Step

示例代码 使用C++来开发WPF,主要是如何在MFC(Win32)的窗口中Host WPF的Page.下面我就做个详细的介绍. 一.创建工程, 由于MFC的Wizard会生成很多用不到的代码,所以我准备从一个空的工程开始创建一个MFC的工程. a)         打开VS2005,菜单File->New->Projects-, 左面选择Visual C++->Win32,右面选择Win32 Console Application,给工程起个名字CPlusPlus_WPF, Ok进入下一

WPF Step By Step 完整布局介绍

WPF Step By Step 完整布局介绍 回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的使用经验,可能还存在错误之处,还请大家指出. 本文大纲 1.Grid 2.StackPanel 3.DockPanel 4.WrapPanel Grid 1.Row和Column 我们下面来介绍Grid的行的用法,及我们在UI设计过程中需要注意的细节. 由于前面我们在第一章中已经介绍了基本的关于Gr