在WPF的MVVM模式中,View和ViewModel之间数据和命令的关联都是通过绑定实现的,绑定后View和ViewModel并不产生直接的依赖。具体就是View中出现数据变化时会尝试修改绑定的目标。同样View执行命令时也会去寻找绑定的Command并执行。反过来,ViewModel在Property发生改变时会发个通知说“名字叫XXX的Property改变了,你们这些View中谁绑定了XXX也要跟着变啊!”,至于有没有View收到是不是做出变化也不关心。ViewModel中的Command脱离View就更简单了,因为Command在执行操作过程中操作数据时,根本不需要操作View中的数据,只需要操作ViewModel中的Property就可以了,Property的变化通过绑定就可以反映到View上。这样在测试Command时也不需要View的参与。这也是我在接触WPF初期时根本理解不了的所谓数据驱动。

这样一来ViewMode可以在完全没有View的情况下测试,View也可以在完全没有ViewModel的情况下测试(当然只是测试界面布局和动画等业务无关的内容)。

1、App中的代码:

public App()

{

    CalculatorView view = new CalculatorView();

    view.DataContext = new CalculatorViewModel();

    view.Show();

}

2、Model层中CauculatorModel的代码

class CauculatorModel

{

     public string FirstOperand { getset; }

     public string SecondOperand { getset; }

     public string Operation { getset; }

     public string Result { getset; }

}

3、Command

public class DeletgateCommand<T>:ICommand

 {

     private readonly Action<T> _executeMethod = null;

     private readonly Func<T,bool> _canExecuteMethod = null;

     public DeletgateCommand(Action<T> executeMethod)

         this(executeMethod, null)

     { }

     public DeletgateCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod) 

     {

         if (executeMethod == null)

             throw new ArgumentNullException("executeMetnod");

         _executeMethod = executeMethod;

         _canExecuteMethod = canExecuteMethod;

     }

     #region ICommand 成员

     /// <summary>

     ///  Method to determine if the command can be executed

     /// </summary>

     public bool CanExecute(T parameter)

     {

         if (_canExecuteMethod != null)

         {

             return _canExecuteMethod(parameter);

         }

         return true;

     }

     /// <summary>

     ///  Execution of the command

     /// </summary>

     public void Execute(T parameter)

     {

         if (_executeMethod != null)

         {

             _executeMethod(parameter);

         }

     }

     #endregion

     event EventHandler ICommand.CanExecuteChanged

     {

         add { CommandManager.RequerySuggested += value; }

         remove { CommandManager.RequerySuggested -= value; }

     }

     #region ICommand 成员

     public bool CanExecute(object parameter)

     {

         if (parameter == null && typeof(T).IsValueType)

         {

             return (_canExecuteMethod == null);

         }

         

         return CanExecute((T)parameter);

     }

     public void Execute(object parameter)

     {

         Execute((T)parameter);

     }

     #endregion

 }

4、ViewModwl层,为了简化,此处Add方法采用硬编码的形式

public class CalculatorViewModel

 {

     CauculatorModel calculatorModel;

     private DeletgateCommand<string> addCommand;

     

     public CalculatorViewModel()

     {

         calculatorModel = new CauculatorModel();

     }

     #region Public Properties

     public string FirstOperand

     {

         get {  return calculatorModel.FirstOperand;  }

         set { calculatorModel.FirstOperand = value;  }

     }

     public string SecondOperand

     {

         get return calculatorModel.SecondOperand; }

         set { calculatorModel.SecondOperand = value; }

     }

     public string Operation

     {

         get return calculatorModel.Operation; }

         set { calculatorModel.Operation = value; }

     }

     public string Result

     {

         get return calculatorModel.Result; }

         set { calculatorModel.Result = value; }

     }

     #endregion

     public ICommand AddCommand

     {

         get

         {

             if (addCommand == null)

             {

                 addCommand = new DeletgateCommand<string>(Add, CanAdd);

             }

             return addCommand;

         }

     }

        

     public  void Add(string x)

     {

         FirstOperand = x;

         SecondOperand = x;

         Result = (double.Parse(FirstOperand) + double.Parse(SecondOperand)).ToString();

         Operation = "+";

         MessageBox.Show( FirstOperand+ Operation +SecondOperand +"=" + Result);

     }

     private static bool CanAdd(string num)

     {

         return true;

     }

 }

ViewModelBase中的代码:

public abstract class ViewModelBase : INotifyPropertyChanged

 {

     public event PropertyChangedEventHandler PropertyChanged;

     protected void OnPropertyChanged(string propertyName)

     {

         PropertyChangedEventHandler handler = PropertyChanged;

         if (handler != null)

         {

             handler(thisnew PropertyChangedEventArgs(propertyName));

         }

     }

 }

5、View层

<Grid>   

       <TextBox  Height="23" Margin="12,63,0,0" Name="textBox1" VerticalAlignment="Top" HorizontalAlignment="Left"  Width="120" />

       <Label Margin="12,25,95,0" Name="label2" Height="32" VerticalAlignment="Top">请输入x的值! x+x=? </Label>

       <Button Height="23" Command="{Binding AddCommand}"

               CommandParameter="{Binding ElementName=textBox1,Path=Text}"   HorizontalAlignment="Left" Margin="12,102,0,0" Name="button1" VerticalAlignment="Top" Width="75">

           确定</Button>

   </Grid>

CommandParameter里传递的是一个参数,当然可以传递多个参数。

MVVM MVC的更多相关文章

  1. MVP MVVM MVC

    上一篇得到大家的关注,非常感谢.由于自己对于这些模式的理解也是有限,对于MVC,MVP,MVVM这些模式的比较,是结合自己的理解,一些地方不一定准确,需要的朋友可以参考下 上一篇得到大家的关注,非常感 ...

  2. 转: GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

    十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...

  3. Extjs6官方文档译文——应用架构简介(MVC,MVVM)

    应用架构简介 Extjs 同时提供对于MVC和MVVM应用架构的支持.这两个架构方式共享某些概念,而且都旨在沿着逻辑层面划分应用程序代码.每种方法在选择如何划分应用组件上都有其各自的优势. 本指南的目 ...

  4. [ExtJS5学习笔记]第九节 Extjs5的mvc与mvvm框架结构简介

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38537431 本文作者:sushengmiyan ------------------ ...

  5. MVC,MVP,MVVM区别联系

    本质上都是MVC,MVC在不同技术中的应用衍生出MVP,MVVM MVC:b/s MVP:c/s,尤其winform MVVM:wpf http://www.codeproject.com/Artic ...

  6. 浅谈MVC和MVVM模式

    MVC I’m dating with a model… and a view, and a controller. 众所周知,MVC 是开发客户端最经典的设计模式,iOS 开发也不例外,但是 MVC ...

  7. 架构模式:MVC与MVVM

    本文探讨如下几个问题: 什么是MVC 什么是MVVM MVC与MVVM对架构属性的影响 MVC实例SpringMVC MVVM实例Vue MVC.MVVM与Layer中的Model,Controlle ...

  8. GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

    十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...

  9. [ExtJS5学习笔记]第九节 Extjs5的mvc与mvvm框架结构简单介绍

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38537431 本文作者:sushengmiyan ------------------ ...

随机推荐

  1. 622FThe Sum of the k-th Powers

    题目大意 求$\sum_{i=1}^{n} i^k$ 分析 我们发现这是一个$k+1$次多项式 因此我们求出前$k+2$项然后插值即可 由于$x_i = i$ 因此公式里面的乘机可以通过预处理然后循环 ...

  2. 16/7/8_PHP-书写规范 PHP Coding Standard

    变量命名规范这里感觉 打算采用 匈牙利命名法+驼峰法命名,因为 PHP是弱类型语言,很多时间因为忽略了变量类型而导致犯一些低级错误.所以在前面加上类型名有助于更好的理解代码. 下载是转载 PHP书写规 ...

  3. vue实现ajax请求(vue-resource和axios)

    1.vue-resouce实现ajax请求 vue1中主要用vue-resouce实现ajax请求, 2.1 引用vue-resouce 引入axios,直接在index.html文件中引入; 或者在 ...

  4. Python程序打包为可执行文件exe

    Python程序打包为可执行文件exe,pyinstaller应用 山重水复疑无路,柳暗花明又一村. 本来是向老师提交一个python程序,因为第一次所以就很尴尬只把源码给老师了,应该是打包成一个可执 ...

  5. PTA 1154 Vertex Coloring

    题目链接:1154 Vertex Coloring A proper vertex coloring is a labeling of the graph's vertices with colors ...

  6. Test Case Design Method - OATS

    [转载] OATS:即Orthogonal Array Testing Strategy,正交表测试策略. 1      OATS的概念: 次数(Runs):简单的说,就是次数是多少,就有多少个用例. ...

  7. hdu6311 Cover (欧拉路径输出)

    hdu6311Cover 题目传送门 题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径. ...

  8. P2324 [SCOI2005]骑士精神(A*)

    P2324 [SCOI2005]骑士精神 A*与爆搜的不同就是它有一个估价函数$h(x)$ 这个估价函数一般设为从当前状态到终点状态的估计最短步数,这样可以有效剪枝 但估计值必须严格小于等于实际剩余步 ...

  9. jQuery easyUI 使用 datagrid 表格

    获取后台数据依旧是使用一般处理程序(ashx) ,分页上添加一个函数(pagerFilter(data)) 前端代码: <%@ Page Language="C#" Auto ...

  10. vue 中使用 watch 出现了如下的报错

    vue 中使用 watch 出现了如下的报错 报错: Method "watch" has type "object" in the component def ...