数据绑定要达到的效果

数据绑定要达到什么效果呢,就是在界面中绑定了数据源之后,数据在界面上的修改能反映到绑定源,同时绑定源的修改也能反映到界面上。从界面反映到绑定的数据源是很容易理解的,因为在绑定过程中我们指定了DataContext和Binding的对象,很容易找到绑定的源并修改。但数据源修改时怎么通知界面呢?因为ViewModel中被绑定的属性并不知道谁绑定了它,如果在ViewModel中存一个View的引用,在数据发生变化时修改View,这无疑又将ViewModel和View耦合在了一起,而且这样做View中相应的控件没有开发完善难以进行测试,同样View中控件类型或名称发生改变时,ViewModel中相关代码都需要修改。在WPF中从数据源通知界面发生变化是通过发送通知的方式进行的,你可以想象一个string类型的Property,名字是TestString,在它发生变化时对着View大喊“TestString发生变化了,你们谁绑定了TestString需要跟着变啊!”,至于绑定的是TextBlock的Text,还是Label的Content,还是TextBox的Text,ViewModel并不关心,同样喊了后结果如何ViewModel也不关心。View在收到这个通知后看有没有绑定 了TestString的地方,找到了就修改,找不到就不管了,也不会在乎这个通知是哪个类型的ViewModel发的。这样ViewModel和View就解耦了,谁也不依赖对方。

INotifyPropertyChanged接口

在WPF中能够实现ViewModel向View喊话功能的就是INotifyPropertyChanged接口,它就像一个大喇叭一样,我们实现了这个接口,就可以通过触发PropertyChanged事件并给出改变的数据源的对象和属性名称,以此来通知数据的变化。这个接口的实现是非常简单的,下图代码就是一种非常简易的实现方式。由于在MVVM中所有的ViewModel和部分Model都需要实现这个接口来达到绑定的效果,因此一般会专门用一个类来实现这个接口,并将这个类作为ViewModel等需要数据更改后发送通知的类的基类。

ObservableCollection<T>集合

NotifyObject貌似把一切都解决了,但是考虑这样一种情况,有一个List<string>列表显示人员名单,View中的一个ListBox绑定了这个列表。每次我们添加新成员时,为了能在View中立即看到结果必须调用RaisePropertyChanged方法让ListBox控件重新加载数据源。这种做法执行了大量的无效操作,就像我们只是改变了屏幕上一小部分内容却要刷新整个屏幕以更新显示一样。如果添加的不是人员而是一种添加动作频繁发生的操作,这种无效操作会极大影响性能。因此WPF提供了一个ObservableCollection<T>集合,可以将数据项的添加、删除等反映到View中绑定的控件上而无需我们做任何操作。所以在遇到对集合添加、删除等操作又需要使用数据绑定时要优先考虑ObservalbeCollection<T>。

数据绑定的示例

有了NotifyObject这个基类后,我们就可以测试数据绑定了。为了让示例针对性更强,该示例仅仅用到了数据绑定,未添加命令绑定等其它内容。示例界面如图所示:

1. 拖动滑块时,最上面TextBox中的数值会跟着变化,显示滑块条的当前值,同时主界面背景色的透明度也会跟着变化。

2. 左下角的DataGrid和右下角的ListBox以及右边标签为下拉菜单的ComboBox中的数据都是一样的。选中这三个控件中的某行时,其它两个控件也会选中该项。右上方紫色方框内会显示选中行的信息。

3. 在左下角DataGrid控件、右下角ListBox控件、右上角紫色区域的某一处修改数据时,其它两处的数据也会随着修改。

下面说明如何通过数据绑定实现上面的功能。

先说一下主界面的ViewModel,其中有double型属性DoubleValue,TestData型属性SelectedData,List<TestData>型属性TestDataList。这里没有使用ObservableCollection集合因为不涉及到集合内数据项的动态添加和删除。如果要使用ObservableCollection也非常简单,只需要把List<TestData>改为ObservableCollection<TestData>即可。

功能1:Slider的Value、TextBox的Text和DockPanel的Background的Opacity都绑定了ViewModel中的DoubleValue。当拖动滑块时,Slider的Value发生了变化,会更新ViewModel中的DoubleValue,DoubleValue更新后会调用RaisePropertyChanged方法触发INotifyPropertyChanged中的PropertyChanged事件,并在事件参数中保存了发生改变的属性名称“DoubleValue”,这样View中绑定了DoubleValue的属性就要更新数据,TextBox的Text属性绑定了DoubleValue,所以TextBox更新了Text以显示最新的Slider的Value。同样主界面最顶层的布局容器DockPanel的Background中的Opacity也绑定了DoubleValue,更改后的表现就是背景色透明度发生了变化。整个过程如图中蓝色箭头所示。

功能2:DataGrid、ComboBox、ListBox的ItemsSource都绑定了ViewModel中的TestDataList,所以他们的列表项都是一样的。在DataGrid中我们显示了TestData的所有属性,ComboBox中我们只显示了StringValue属性,在ListBox中则重写了数据项模板,按照我们想要的方式显示TestData中的BoolValue、AddDateTime、和IntValue。同时这三个控件的SelectedItem也都绑定了ViewModel中的SelectedData,因此当其中一个的选中项发生改变时,其它两个控件的选中项也会相应发生改变,原理参照功能1。此外右上角紫色区域的几个TextBox和一个CheckBox分别绑定了SelectedData的不同属性,因此当SelectedData发生改变时,紫色区域内各个控件的显示内容也会发生改变。

功能3:因为TestData类也继承自NotifyObject,而且几个属性在发生改变时也会调用RaisePropertyChanged方法发出通知,因此所有绑定了这些属性的控件也会随着更新数据。表现出来就是在任何地方修改了TestData中的属性,所有绑定了这些属性的控件都会更新。

当然了,还需要在主界面的后台代码中把DataContext设置为ViewModel的一个实例。

DataContext = new MainWindowViewModel();

其实上面很多功能可以不借助ViewModel来实现的。例如功能1中把TextBox的Text直接绑定到Slider的Value上,同样功能二中ListBox的SelectedItem也可直接绑定到DataGrid的SelectedItem上,之所以使用ViewModel是为了演示MVVM模式下的数据绑定。

MVVM模式的 数据绑定的更多相关文章

  1. C# Note7:MVVM模式之数据绑定

    一.资源说明 (1)本文参考自: 一步步走进WPF的MVVM模式(二):数据绑定 WPF之数据绑定总结 二.正文  数据绑定 (Data Binding)是WPF最重要的特性之一,也是实现 MVVM( ...

  2. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  3. WPF中使用MVVM模式进行简单的数据绑定

    计划慢慢整理自己在WPF学习和工作应用中的一些心得和想法,先从一个简单的用法说起 在WPF中,XAML标记语言中绑定数据,而数据源就是指定为ViewModel类,而非界面本身的逻辑代码类 这样一定程度 ...

  4. Android进阶笔记13:RoboBinding(实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架)

    1.RoboBinding RoboBinding是一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架.从简单的角度看,他移除了如addXXListen ...

  5. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  6. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  7. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  8. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  9. [转载]MVVM模式原理分析及实践

    没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...

随机推荐

  1. laravel运行慢是怎么回事?

    因为默认的 hello 页面引用了 google 的字体,至于为什么 google 这么慢就不用我详细说明了吧.

  2. BZOJ 3166: [Heoi2013]Alo

    3166: [Heoi2013]Alo Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 923  Solved: 437[Submit][Status] ...

  3. 51nod 1471 小S的兴趣 | 分块 链表

    51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...

  4. 洛谷 P3698 [CQOI2017]小Q的棋盘 解题报告

    P3698 [CQOI2017]小Q的棋盘 题目描述 小 Q 正在设计一种棋类游戏. 在小 Q 设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上 ...

  5. vim配置高亮显示

    经常使用SecureCRT在linux下修改一些配置文件,使用vi打开总是一个颜色,找起来比较头大. 因为vi不支持高亮,所以需要使用vim. 安装vim:yum install -y vim(ubu ...

  6. 题解【bzoj2733 [HNOI2012]永无乡】

    Descriprition 两种操作 把两个集合并起来 求一个集合中的第 \(k\) 大(的编号) \(n \leq 10^5\) Solution 平衡树的板子题之一 维护两个点连不连通直接并查集 ...

  7. Java入门:一些初学者需要掌握的基础算法程序——二分查找

    本例演示如何通过二分算法查找一个链表中的指定元素. import java.util.Scanner; class BinarySearchExample { public static void m ...

  8. my-innodb-heavy-4G.cnf配置文件注解

    [client] ####客户端 port = 3306 ####mysql客户端连接时的默认端口号 socket = /application/mysql-5.5.32/tmp/mysql.sock ...

  9. 大量DOM操作的解决方案

    案例:如何在页面元素ul中一次性插入30000个li标签,保证页面体验流畅呢? 解决方案:可以从减少 DOM 操作次数.缩短循环时间两个方面减少主线程阻塞的时间 减少 DOM 操作次数的良方是 Doc ...

  10. ASP.NET配置文件Web.config 详细解释

    一.认识Web.config文件 Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式), ...