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

简介: 原文:[译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)  应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等。
原文: [译]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的值也发生了变化。

 

目录
相关文章
|
2月前
|
前端开发 测试技术 数据处理
Kotlin教程笔记 - MVP与MVVM架构设计的对比
Kotlin教程笔记 - MVP与MVVM架构设计的对比
83 4
|
2月前
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
34 2
|
1月前
|
算法 NoSQL Java
微服务架构下的接口限流策略与实践#### 一、
本文旨在探讨微服务架构下,面对高并发请求时如何有效实施接口限流策略,以保障系统稳定性和服务质量。不同于传统的摘要概述,本文将从实际应用场景出发,深入剖析几种主流的限流算法(如令牌桶、漏桶及固定窗口计数器等),通过对比分析它们的优缺点,并结合具体案例,展示如何在Spring Cloud Gateway中集成自定义限流方案,实现动态限流规则调整,为读者提供一套可落地的实践指南。 #### 二、
70 3
|
2月前
|
设计模式 缓存 架构师
架构师必备10大接口性能优化秘技
【11月更文挑战第25天】在软件开发中,接口性能优化是架构师必须掌握的关键技能之一。一个高效的接口不仅能够提升用户体验,还能减少服务器资源消耗,提高系统稳定性。本文将介绍10大接口性能优化秘技,并通过Java示例代码展示这些技巧在实际业务场景中的应用。
52 3
|
2月前
|
缓存 负载均衡 监控
微服务架构下的接口性能优化策略####
在当今快速迭代的软件开发领域,微服务架构以其灵活性和可扩展性成为众多企业的首选。然而,随着系统复杂性的增加,接口性能问题日益凸显,成为制约用户体验与系统稳定性的关键因素。本文旨在探讨微服务架构下接口性能优化的有效策略,通过具体案例分析,揭示从代码层面到系统架构层面的全方位优化路径,为开发者提供实战指南。 ####
|
2月前
|
XML 前端开发 Android开发
Kotlin教程笔记(80) - MVVM架构设计
Kotlin教程笔记(80) - MVVM架构设计
|
2月前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
69 6
|
2月前
|
存储 Dart 前端开发
flutter鸿蒙版本mvvm架构思想原理
在Flutter中实现MVVM架构,旨在将UI与业务逻辑分离,提升代码可维护性和可读性。本文介绍了MVVM的整体架构,包括Model、View和ViewModel的职责,以及各文件的详细实现。通过`main.dart`、`CounterViewModel.dart`、`MyHomePage.dart`和`Model.dart`的具体代码,展示了如何使用Provider进行状态管理,实现数据绑定和响应式设计。MVVM架构的分离关注点、数据绑定和可维护性特点,使得开发更加高效和整洁。
181 3
|
2月前
|
XML 前端开发 Android开发
Kotlin教程笔记(80) - MVVM架构设计
Kotlin教程笔记(80) - MVVM架构设计
|
3月前
|
存储 前端开发 测试技术
Android kotlin MVVM 架构简单示例入门
Android kotlin MVVM 架构简单示例入门
53 1