WPF的数据绑定笔记摘录

原创 2012年03月31日 00:17:10

所谓数据绑定,其概念很简单,数据绑定决定了一个Source的改变会不会,以及怎样自动通知并改变Destination。

Source可以是数据表,可以是XML,可以是一个内存数据,也可以是一个控件的某个属性值。

Destination必须是一个Dependency Object的某个属性。

这样的设定,使得数据的需求者(往往同时也是业务的处理者)和界面的提供者得以松绑。数据需求者仅需完成本身的业务逻辑,例如,被击中导致当前玩家掉血10点。至于这个减掉的10点如何在界面逻辑中表现,这个完全跟业务没关系,我一个业务的制作者没有知道它的必要。

这样的松绑看似简单,但解决了一个潜在的问题:界面的开发往往比业务更费时费力,松绑后,业务可以极速地实现并投入测试,而界面则可以快速地铺量、修改、变化,而不用因此牵扯到任何逻辑和业务流程。

数据绑定事实上并不需要去参考WPF的实现,C++实现的数据绑定一抓一把,UE3什么的实现都中规中矩,但WPF确实是一个很经典的体系,而且很清晰的概念。

木有代码?呃,您可以Reflector其……



基本来说,这么几个流程,我们先按照最简单的OneWay来说:


有这么几个概念:源数据,就是将要发生改变的属性所在的数据,里面包含大量属性,其中有一个即将发生改变。目标数据,就是将要因为源改变而改变其属性的数据。Binding:指示“对源数据中的X元素的修改”将使得我“修改目标数据中的Y属性”。


首先,源数据必须实现INotifyPropertyChange接口,这个接口实际上指明了源数据这个对象中必须有一个event,可以挂接一个OnPropertyChanged的代理。

Dependency Object虽然没有显示实现这个接口,但因其内部调用流程做了特殊处理,因此可以理解为实现了这个接口,所以WPF界面元素中的很多属性基本上都支持了数据绑定。


然后,解析时,发现了这个Binding对象,就会将这个Binding对象的相应方法以代理的形式注册到这个event中。

所以WPF的使用者绝对不会注意到有一个这个接口存在,因为你根本不必手动调用它。


再然后,Source发生了变化。

这时,如果是Dependency Object派生类的属性发生变化,因为一般调用的都是SetPropertyValue(DependencyProperty, value),这个方法内部自动就会调用OnPropertyChanged代理,转而调用了Binding对象的相应方法,而Binding对象的相应方法将按照配置,寻找到目标元素的目标属性,通知其已被改变。

而如果是用户自定义的数据结构呢?那您必须实现INotifyPropertyChange接口,这样Binding才可能把自己挂到Source上,并在Source发生变化时(这时机你一定是知道的)通知OnPropertyChanged代理。


有这三步基本就齐活,剩下的就无非是一些中间检查是否实现了接口之类的工作,是否有Convertor,以及数据改变后,触发动画之类的工作了。

于此类同,ItemsControl对ItemsSource要求一定要实现INotifyCollectionChange接口,跟这套东西基本上是一样的。


由此可以总结出数据绑定关键的几个组分:

必须要有一个数据源,这个数据源知道自己属性什么时候将要发生更改(也就是必须调用数据源的方法使得其属性发生更改),发生更改时,数据源将通知绑定者。

必须要有一个绑定者,绑定者接收到数据源的改变通知后,根据自己的配置,决定接下来使得哪些或者哪个目标属性得到改变。

目标和目标属性,就不用说了。

只要完成了这几个组分,基本上数据绑定就没的跑了。

而这几个组分的关键就在于目标属性和绑定者采取什么方法互相访问和存储,这个可以根据当前的情况自由选择了。

对于WPF,您可以认为Binding存储于Dependency Object的值表中。这就体现出来了WPF这个Dependency Property设计的优势,值表里的所有值都是无差别的object,其类型是由Dependency Property来决定的,所以用这些object存一个int可以,存一个Binding也是松松的,无非就是个怎么取得数据的问题,都知道数据有改变了,怎么获取,就应该不是问题了吧?

而xaml脚本的Binding会被解释为FrameworkElement的SetBinding调用,实际上就将Binding对象本身设到了这个值表中,同时,向源中挂接自己的代理。源改变了,Binding得到通知,然后通知挂接者(某个Dependency Object)相应的Property发生了变化,Property再去值表中取得当前的真实值,再通知其它逻辑自己发生了改变即可。



备注:WPF的Dependency Object体系

Reflector了WPF的数据绑定实现,会发现它本身实现其实没有多复杂,但是却跟我们平常对事物的认识稍有不同,所以这里解释一下:一般来说我们来写一个程序,总是习惯性地去划分好模块关系、类的关系、对象关系,类里面有哪些成员是死的,对象之间的调用型是既定的。然而WPF数据绑定完全不同。WPF数据绑定的核心同时就是它所有UI元素的基类:Dependency Object。事实上,Dependency Object这套体系唯一所做的一切事情,就是打破了“类里面的成员是死的”这个基本假设。

C#本身已经具有许多动态语言的特性了,但是毕竟还是一个编译语言,这就注定很多东西一旦编译就不能再改变了。如果顺着这个思路做下去,迟早是另一套MFC,程序员的思维去做界面,那干嘛要做WPF和Silverlight呢。而Dependency Object这样的方法就比较巧妙了,实际上相当于在C#上又构建了一个……呃,怎么说呢?虚拟机?它自己用自己的方式来保存属性(Dependency property),自己解析,自己按照自己的方式来处理。

Dependency Object的实现很简单,所有的Dependency Object都是一样的,基本没有什么有意义的数据成员,最关键的是保存了一个值表,Cache了每个Property的取值,可以是实值,也可以是Binding。而每向一个Dependency Object类注册一个static Dependency Property,虽然不是真刀真枪地在Class里面写了一个,其概念相当于为这个类增加了一个属性。SetProperty的过程,就是通过Property找到相应的值表元素,并且修改之的过程。

所以你看到某个具体的WPF类,可以将其视为一个具体的C++类,而Dependency Property就可以将其理解为一个具体的C++成员变量。而WPF之所以要费尽这么写,主要是为了做一系列的内部工作。

而对于咱们来说,真正关键的只是这些内部工作,其中最主要的是两个,一个是自己改变时调用Binding代理的这个过程,另一个就是值表这个东西。



跟着看挺痛苦的,去年这时候跟的这个东西,然后写了一堆笔记,最近要做这个东西所以重新整理了一下之前的笔记,写了这篇文字。中间的很多东西是提炼出来的,也有一些是根据印象整理的,可能有所疏漏,有些地方也是简化了不少,不过基本上应该就是这个思路了。

自己实现的绑定系统基本快要完成了,那之前再聊聊UE3又是怎么处理这个问题的,对比一下。敬请期待下文。

WPF 数据绑定详解。。。

数据绑定 控件之间的绑定 绑定源 source  数据提供者 绑定对象 target  接受数据的对象,被绑定的对象 对 绑定对象 进行数据绑定,将其的属性,和绑定源的某个属性进行绑定 ...
  • rsj217
  • rsj217
  • 2013年08月14日 14:08
  • 2071

WPF 简单数据绑定实例

创建一个WPF窗体,加一个TextBox和Button控件,控件button用于控制数据更改,TextBox用于显示更改后的数据,这项数据对于WinForm来说是很容易实现的,用控件点击事件对另一个控...
  • loveyou388i
  • loveyou388i
  • 2017年04月14日 11:05
  • 638

WPF之数据绑定总结

最近几天高强度开发,暴露出不少问题,WPF还达不到信手拈来的地步,好些东西还要去看看以前的项目。平时还是要多总结的,层次高了之后关注的知识点才会更深入。下面总结下WPF的绑定相关,总结之前又看了一遍深...
  • pfe_Nova
  • pfe_Nova
  • 2014年02月15日 18:00
  • 21907

word居然可以这么强大(转自莫名其妙的笔记)

把文字替换成图片 首先把图片复制到 剪贴板中,然后打开替换对话框,在“查找内容”框中输入将被替换的文字,接着在 “替换为”框中输入“^c”(注意:输入的一定要是半角字符,c要小写),单击替换 即可。说...
  • dgglx
  • dgglx
  • 2010年12月09日 17:51
  • 1704

WPF数据绑定机制是如何实现

接触MVVM模式也有一段时间了,这种将前后台分离开了的设计模式一下子就吸引了我,也是当时一直有一个问题困扰了我很久:WPF是如何实现数据变动通知的。 通过查询各种资料,自己反复推敲实验,终于发现这种...
  • liebert
  • liebert
  • 2017年09月19日 23:01
  • 400

WPF学习笔记之-WPF数据绑定

WPF数据绑定一、数据绑定基本概念 既然是绑定,那么肯定就有”源对象“和”目标对象“两种状态实体,从图的角度上来说存在三种状态: 确实在wpf中存在这三种模式的对应方式, ...
  • afjafjafj2008
  • afjafjafj2008
  • 2015年02月25日 17:44
  • 1268

WPF数据绑定-简单对象的绑定

绑定自定义的数据类对象 在xaml代码中,Binding标记扩展中仅定义了Path属性,将它绑定到StudentData类的属性上。不需要定义源对象,因为通过指定DataContext类定义源对象...
  • i1tws
  • i1tws
  • 2017年03月28日 22:15
  • 3211

WPF 中的数据绑定

WPF 中的数据绑定 John Papa 代码下载位置: DataPoints2007_12.exe (161 KB)  Browse the Code Online ...
  • findsafety
  • findsafety
  • 2014年02月21日 11:26
  • 1629

Windows Presentation Foundation(WPF)中的数据绑定(控件与控件值的绑定)

--------------------------------------------------------------------------------引用或转载时请保留以下信息:大可山 [M...
  • johnsuna
  • johnsuna
  • 2007年08月21日 14:51
  • 3102

WPF自定义控件数据绑定——双向绑定

自己整了一个自定义控件UserControl,功能就是一个带拼音筛选功能的ComboBox,不过发现数据绑定dataset的row的一列之后可以显示值,但是更改之后不能更改到row里,在textbox...
  • keyler
  • keyler
  • 2011年11月08日 17:16
  • 7885
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WPF的数据绑定笔记摘录
举报原因:
原因补充:

(最多只允许输入30个字)