WPF Binding

Binding的亮点

  在WPF中,Binding无处不在,关于Binding的漂亮用法有很多,其主要的设计亮点有二:

  1. Weak Event模式
  2. Converter

  监听B的属性变化,A需要注册B的PropertyChanged事件,.net中事件是强引用,一旦A注册了B的事件,B就持有了一个A的引用。也就是说,如果A不注销B的事件,即使A已经空置,如果B对象存活,垃圾回收器仍不会回收A的内存,在使用中就造成了A的内存泄露。在Binding的使用过程中,可能会出现多级绑定,A->B->C,一个对象也可能绑定多个对象,在对象空置时注销绑定的监听事件是不太现实的,实现起来太过繁琐。这里就期望能有弱事件(Weak Event)模式,即A监听了B的事件后,B不会阻止A的垃圾回收。

直接把A的属性绑定到B的属性上有时也是不太友好的,比如B的属性是string,A的属性是DateTime,在绑定的过程中需要做一定的转换(Convert)。WPF/Silverlight中的Converter是很不错的想法,可以自定义一些转换,在属性间做一些转换工作。

设计

  开始设计实现BindingEngine,首先来解决弱事件的问题。

  在.net中,可以使用WeakReference(弱引用)来监视对象,WeakReference不会阻止对象的垃圾回收。在实际使用中,A注册B的事件后,B持有了A的引用,B对象会阻止A的垃圾回收。直接把B对象变成弱引用对象是不现实的,但可以引入弱引用对象C,让B持有C的引用,C持有A的引用。这样即使没有注销事件监视,C对象仍持有A的引用,但是C对象是弱引用对象,不会阻止A的垃圾回收。

  用一副图表示:

image

  把用来作为中间传递的C类命名为WeakSource,它的设计如下:

image

  WeakSource用来隔离A对象,为了内存考虑,它和A对象间是一一对应关系。这样,在监听B的PropertyChanged事件时,原有的b.ProppertyChanged += a.HandlePropertyChanged就变成了b.PropertyChanged += weakSource.HandlePropertyChanged。WeakSource提供了两个静态方法Register和UnRegister来创建和销毁WeakSource,其中的第一个参数object Source就是WeakSource需要封装的A对象。

  Register的第二个参数INotifyPropertyChanged target,就是需要监听的B对象,最后一个参数targetProp是需要监听B对象的属性名。当B的属性值发生变化时,WeakSource会得到通知,为了完成绑定,WeakSource需要把内部封装的A对象对应的属性值设置为B对象绑定属性的新值。

 

文章来源:http://www.cnblogs.com/Zhouyongh/archive/2011/03/09/1977768.html

原文地址:https://www.cnblogs.com/luohengstudy/p/3110822.html