• 从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第六讲 WPF MVVM开发模式


    现在MVVM遍地都是,各种实现方式都有,不过说到头都离不开 View Viewmodel Model

    对于之前用Winfrom做项目开发工具的朋友来说,用WPF来开发项目估计会有点痛苦,尤其要用MVVM模式来做项目开发框架,更是感到揪心,很难拍拖那种把view 和viewmodel完全解耦的那一种思路。

    在我们开始做项目之前,建议大家准备一些准备一些东西,不如环境的配置,插件的安装,三方控件的准备,建议下载一个Resharp,Break on CLR exception, Snoop 之类的,方便以后开发,

    下面就开始我们的MVVM之旅吧。

    MVVM具有很大的灵活性,但无论怎么分,需要干的事情还是需要干,只不过从直接变为了间接。从分离分工的角度来说这种方式很好,但对于编程的简洁性来说,其实是不利的。而且大量的利用发射机制,性能上的损失会比较大,不过,你选择使用这种方式,就意味着你可以忍受一定的性能损失,而换取它的好处。目前来说,MVVM模式我觉得对于交互简单的页面还是非常好,但对于页面交互逻辑比较复杂的情况,还是非常不利。比如关联性交互,就是一个控件的状态发生改变,其它的控件也会跟着改变,甚至交互逻辑也会改变,直接控制变为间接控制就非常麻烦,到最后,采用这种MVVM模式会使得,VM其实就成了页面的又一个的.cs文件。

    其实我们在使用MVVM模式时,没必要完全拘泥于这种理论性指导,虽然,我们可以尽可能的朝着MVVM的目标走,但如果确实需要在.cs控制,那么就大胆的用。因为大部分的示例大多时候都只能反映事情的一个面。

    总之用MVVM会大量减少你代码的维护成本,会使得IT,UT写起来更加简单,方便。

    一、关于WPF

              WPF(Windows  Presentation Foundation) ,从名字来看,Microsoft想把WPF技术作为Windows程序外观(表现层)的基础。我们知道,现在开发一套系统,一般都会采用分层架构,最基本的层次会包含表现层,逻辑层,和数据层,总之如果是GUI程序,就需要有表现层。WPF技术就是用来实现表现层的技术,在实际开发中就是做界面,做UI,它可以让界面做的非常酷,而且实现这些酷的效果并不太费力。另外是WindowsCommunication Foundation及 Windows Workflow Foundation。

     

      一句话总结:WPF是在Windows平台上用来开发GUI程序的表现层的技术

     

    二、GUI开发的历史

     

    1、WindowsAPI + C语言

    最早的开发WindowsGUI程序的思路。用C语言直接调用Windows操作系统提供的API函数来开发,程序员处理Windows消息。经历过这段开发时期的程序员一般对底层比较清楚,要了解Windows操作系统的工作原理。

    2、MFC +C++

    MicrosoftFoundation Class(MFC),微软用C++封装了Win32 API, C++程序员通过使用MFC类库来开发。面向对象的编程方法。

    3、WinForm+ C#

    微软推出.net平台后,Winform程序是.net平台中的技术,它把WinAPI封装成了控件。

    4、WPF +C#

    当然也是基于.net平台的技术,从.netframwork3.0开始推出WPF技术。WPF的特点是数据驱动,而以上三者是消息驱动或事件驱动的开发模式。从图像系统角度看,WPF对图形的展示是直接使用directX技术,而其他三者是基于GDI/GDI+技术,因此WPF在图形图像处理方面很优越,提高了用户体验。

     

      其他还有一些VB+ActiveX控件,JavaSwing,Delphi等开发模式,这些不太熟悉,就不多说了。

     

      我们知道,目前的应用程序很注重用户体验,而且程序的规模也越来越大,上述的技术演变刚好可以看出这点,从面向过程编程方法演变到面向对象方法,再演变到组件化方法,这都是为了提供开发效率,而WPF的出现,使应用程序在用户体验上,界面的展现效果更佳。

     

    三、WPF的优缺点

    从2007年开始WPF作为.netframework3.0中的一项重要技术发布,版本号也跟随.netframework叫WPF3.0,随后发布了WPF3.5,WPF3.5SP1,WPF4.0,WPF4.5。随着版本的不断更新,WPF的能力也越来越强,其应用也越来越多。开发微软最新推出的平台应用,如: windows8, surface,windows phone8等程序,基本都要用到WPF技术。

     

    其优缺点:

    优点:

    1、使用DirectX技术,图形图像处理能力强。相对于Winform或更早的技术,WPF实现的界面效果优越很多。

     

    2、代码后置(Code-Behind)更彻底,设计师可以用Xaml语言来设计UI,同时程序员可以开发后台交互逻辑,最后很容易集成到一起,如果需要更换界面,更换Xaml文件的设计即可。相比于之前的Winform程序,在开发流程上一定的并行化,换肤更简单。不过目前看来Blend比不上PhotoShop。所以很多设计师还是用Photoshop来实现效果图。而程序员要想做好WPF程序,也需要学习好Xaml,实现界面效果。

     

    3、最重要的一点是,WPF是数据驱动UI的模式,相比Winform或之前的技术,它们都是通过UI来驱动数据的改变。数据驱动UI也就是说,UI控件的样子不是固定的,UI控件只是对数据的展示,而以什么样的形态来展示给用户,完全取决于控件的模板和样式,也就是说按钮不一定是一个矩形的,你可以让它变成圆形。随着学习,慢慢会体会到WPF的强大。

     

    缺点:性能不好,对硬件要求高。

     

    四、关于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的简单案例

     

    框架视图:

     

    各个文件源码:

    MainWindow.cs:

     

    namespace WpfMvvm
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = new ViewModel();
            }
        }
    }

    Model.cs:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.ComponentModel;
    using System.Windows.Input;
    
    namespace WpfMvvm
    {
        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";
            }
    
        }
    }

    Notification.cs:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ComponentModel;
    
    namespace WpfMvvm
    {
        class NotificationObject:INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void RaisePropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }

    ViewModel.cs:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WpfMvvm
    {
        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);
            }
        }
    }
    

    DelegateCommand.cs:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Windows.Input;
    
    namespace WpfMvvm
    {
        class DelegateCommand:ICommand
        {
            public Action<object> ExecuteCommand = null;
            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);
                }
            }
        }
    }
    

    关于MVVM的基础,我这里就不再强调很多了,这里有一篇关于MVVM模式的入门级讲解,讲的还算容易明白的,没有MVVM基础的可以参考这里,原文地址http://doc.okbase.net/ling45480867/archive/18118.html

    下篇开始就进入我们框架的搭建了,谢谢支持。

  • 相关阅读:
    BZOJ 1041: [HAOI2008]圆上的整点
    BZOJ 1040: [ZJOI2008]骑士
    BZOJ 1037: [ZJOI2008]生日聚会Party
    BZOJ 1034: [ZJOI2008]泡泡堂BNB
    BZOJ 1032: [JSOI2007]祖码Zuma
    BZOJ 1031: [JSOI2007]字符加密Cipher
    BZOJ 1030: [JSOI2007]文本生成器
    Flink学习(三) 批流版本的wordcount Scala版本
    Flink学习(三) 批流版本的wordcount JAVA版本
    Flink学习(二) 应用场景和架构模型
  • 原文地址:https://www.cnblogs.com/hwy425/p/4975970.html
Copyright © 2020-2023  润新知