zoukankan      html  css  js  c++  java
  • MVVM示例讲解

    本篇从两个方面来讨论MVVM模式:

    1. MVVM理论知识
    2. MVVM示例讲解

    一,MVVM理论知识

      从上一篇文章中,我们已经知道,WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI。 

      我们使用模式,一般是想达到高内聚低耦合。在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般在后置代码中会使用控件的名字来操作控件的属性来更新UI,而在WPF中通常是通过数据绑定来更新UI;在响应用户操作上,WinForm是通过控件的事件来处理,而WPF可以使用命令绑定的方式来处理,耦合度将降低。

      我们可以通过下图来直观的理解MVVM模式:  

      View就是用xaml实现的界面,负责与用户交互,接收用户输入,把数据展现给用户。
      ViewModel,一个C#类,负责收集需要绑定的数据和命令,聚合Model对象,通过View类的DataContext属性绑定到View,同时也可以处理一些UI逻辑。
      Model,就是系统中的对象,可包含属性和行为。

      一般,View对应一个ViewModel,ViewModel可以聚合N个Model,ViewModel可以对应多个View,Model不知道View和ViewModel的存在。

    二,MVVM示例讲解

      这个示例是为了让大家直观地了解MVVM的编程模式,关于其中用到的数据绑定和命令等知识,在后面的文章会专门讨论。

    1. 首先定义NotificationObject类。目的是绑定数据属性。这个类的作用是实现了INotifyPropertyChanged接口。WPF中类要实现这个接口,其属性成员才具备通知UI的能力,数据绑定的知识,后面详细讨论。
    复制代码
    using System.ComponentModel;
    
    namespace WpfFirst
    {
        class NotificationObject : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void RaisePropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }
    复制代码

      2.定义DelegateCommand类。目的是绑定命令属性。这个类的作用是实现了ICommand接口,WPF中实现了ICommand接口的类,才能作为命令绑定到UI。命令的知识,后面详细讨论。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Windows.Input;
    
    namespace WpfFirst
    {
        class DelegateCommand : ICommand
        {
            //A method prototype without return value.
            public Action<object> ExecuteCommand = null;
            //A method prototype return a bool type.
            public Func<object, bool> CanExecuteCommand = null;
            public event EventHandler CanExecuteChanged;
    
            public bool CanExecute(object parameter)
            {
                if (CanExecuteCommand != null)
                {
                    return this.CanExecuteCommand(parameter);
                }
                else
                {
                    return true;
                }
            }
    
            public void Execute(object parameter)
            {
                if (this.ExecuteCommand != null) this.ExecuteCommand(parameter);
            }
    
            public void RaiseCanExecuteChanged()
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }
        }
    }
    复制代码

      3.开始定义Model类。一个属性成员"WPF",它就是数据属性,的有通知功能,它改变后,会知道通知UI更新。一个方法“Copy”,用来改变属性“WPF”的值,它通过命令的方式相应UI事件。

    复制代码
    using System.ComponentModel;
    using System.Windows.Input;
    
    namespace WpfFirst
    {
        class Model : NotificationObject
        {
            private string _wpf = "WPF";
    
            public string WPF
            {
                get { return _wpf; }
                set
                {
                    _wpf = value;
                    this.RaisePropertyChanged("WPF");
                }
            }        
    
            public void Copy(object obj)
            {
                this.WPF += " WPF";
            }
            
        }
    }
    复制代码

      4.定义ViewModel类。定义了一个命令属性"CopyCmd",聚合了一个Model对象"model"。这里的关键是,给CopyCmd命令指定响应命令的方法是model对象的“Copy”方法。

    复制代码
    using System;
    namespace WpfFirst
    {
        class ViewModel
        {
            public DelegateCommand CopyCmd { get; set; }        
            public Model model { get; set; }
    
            public ViewModel()
            {
                this.model = new Model();
                this.CopyCmd = new DelegateCommand();
                this.CopyCmd.ExecuteCommand = new Action<object>(this.model.Copy);
            }
        }
    }
    复制代码

      5.定义View.

      MainWindow.xaml代码:我们能看到,TextBlock控件的text属性,绑定在model对象的WPF属性上; Button的click事件通过命令绑定到CopyCmd命令属性。  

    复制代码
    <Window x:Class="WpfFirst.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <StackPanel VerticalAlignment="Center" >
                <TextBlock Text="{Binding model.WPF}" Height="208" TextWrapping="WrapWithOverflow"></TextBlock>
                <Button Command="{Binding CopyCmd}" Height="93" Width="232">Copy</Button>
            </StackPanel>
        </Grid>
    </Window>
    复制代码

      MainWindow.xaml.cs代码:它的工作知识把ViewModel对象赋值到DataContext属性,指定View的数据源就是这个ViewModel。

    复制代码
    using System.Windows;
    
    namespace WpfFirst
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                this.DataContext = new ViewModel();
            }
        }
    }
    复制代码

      6.运行结果。每当我们点击按钮,界面就是被更新了,因为Copy方法改变了WFP属性的值。  

      写这个简单的例子,就是为了直观地了解MVVM的编程模式。在实际开发中,不管程序有多复杂,也就是增加Model, View, ViewModel,和其他的一些辅助类(Helpers or Services)了,模式不会改变。

     
    分类: WPF技术
    标签: WPF MVVM
  • 相关阅读:
    I.MX6 Surfaceflinger 机制
    理解 Android Fragment
    RPi 2B DDNS 动态域名
    RPi 2B IPC webcam server
    理解 Android MVP 开发模式
    I.MX6 system.img unpack repack
    can't set android permissions
    VMware Ubuntu 共享文件夹
    解决oracle数据库连接不上的问题
    perfect-scrollbar示例
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2769980.html
Copyright © 2011-2022 走看看