WPF DataBinding

1. What is DataBinding?

         数据绑定是在UI和业务逻辑间建立一个连接的过程,如果绑定有被正确的设置以及数据提供了合适的通知机制,则当数据改变时,被绑定这个数据的元素会自动的反应这个变化。
2. Basic Data Binding Concepts
        无论你用何种绑定target和绑定source,所有的绑定都遵循下面的绑定关系:

wpf databinding(1).jpg

这个特性说明了以下几点

(1): 每个绑定都有四个要素, binding target object、binding target property、binding source、以及绑定间的关系。例如我们将一个Employee对象的Name属性作为source绑定到一个TextBox的Text属性上。
(2): target property 必须是Dependency property, 而且只有在Dependency object内部才能定义Dependency property。
(3): binding source没有被限定为只能是CLR object,例如一个包含xml data的xml,Ado.Net的数据都可以当作绑定源。

必须注意的是,当实现一个绑定的时候,我们是绑定一个binding target到一个binding source。而不是反过来。

Direction of the Data Flow:

下图说明了几种绑定过程中数据流的方向:

wpf databinding(2).jpg

(1): OneWay, 当source改变时,target property会自动的改变。
(2): TwoWay, 当任意一个property改变时,另一个会自动的改变。
(3): OneWayToSource, 当target property改变时,source会自动的改变。这适合于仅要根据UI的变化来评价source value的变化。
(4): OneTime, 和OneWay的绑定方向一样,但是只绑定一次。它适合于source不改变或者以后的改变不需要反映到target上的情况,可以提高性能。

需要注意的是为了监测到source 的变化(在OneWay和TwoWay的绑定中),source需要实现必要的通知机制,例如实现INotifyPropertyChanged接口。

What causes the source updates?

在TwoWay和OneWayToSource的绑定中,target的改变是怎样通知source的呢?这是通过设置UpdateSourceTrigger属性达到的。
它有三个枚举值,LostFocus、PropertyChanged和Explicit。不同的控件默认的该值是不同的,例如CheckBox默认的是PropertyChanged,而TextBox为了提高性能,则是LostFocus。而Explicit则是需要显式的调用了,例如:
<TextBox Name="itemNameTextBox"

         Text="{Binding Path=ItemName, UpdateSourceTrigger=Explicit}" />















这样则只有当程序中调用UpdateSource()方法是,source才更新:
















// itemNameTextBox is an instance of a TextBox


BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty); be.UpdateSource();






3. Creating a Binding


例如下面的例子,binding source object是一个MyData类,定义在SDKSample名空间中,MyData类有一个string类型的属性ColorName,被设置成"Red":

<DockPanel
  xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation "
  xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml "
  xmlns:c="clr-namespace:SDKSample">
  <DockPanel.Resources>
    <c:MyData x:Key="myDataSource"/>
  </DockPanel.Resources>
  <DockPanel.DataContext>
    <Binding Source="{StaticResource myDataSource}"/>
  </DockPanel.DataContext>
  <Button Background="{Binding Path=ColorName}"
          Width="150" Height="30">I am bound to be RED!</Button>
</DockPanel>

注意在这个例子中,binding source object的指定是通过DockPanel.DataContext属性指定的,因为Button在DockPanel的内部,所以Button会继承DockPanel的DataContext属性的。
这种在父Element中设置DataContext适用于有多个绑定属性时,而只有一个source object,方便。当然我们可以更方便的使用下面的方式:
<DockPanel.Resources>
  <c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<Button Width="150" Height="30"
        Background="{Binding Source={StaticResource myDataSource},
                             Path=ColorName}">I am bound to be RED!</Button>

Binding and BindingExpression类:

一个Binding类实例提供了binding source的信息,一个BindingExpression类实例则负责把这个binding source和一个target连接起来。因为可以把一个source绑定到多个不同的target,所以这么多BindingExpression实例就共享一个binding类的实例,如下例:

Code
先建立一个binding:

MyData myDataObject = new MyData(System.DateTime.Now.ToShortDateString());
Binding myBinding = new Binding("MyDataProperty");  // 参数是Binding的path。
myBinding.Source = myDataObject;

下面是两个BindingExpression都用这个binding:

myText.SetBinding(TextBlock.TextProperty, myBinding);
myCheck.SetBinding(
CheckBox.ContentProperty, myBinding);

我们可以通过BindingOperations类在运行时获得这些信息:

Binding b1 = BindingOperations.GetBinding(myText, TextBlock.TextProperty);
BindingExpression be1 = BindingOperations.GetBindingExpression(myText, TextBlock.TextProperty);
BindingExpression be2 = BindingOperations.GetBindingExpression(myCheck, CheckBox.ContentProperty);

4. Data Conversion

具体参见Data Conversion

5. Binding to collections

除了绑定到单个object之外,很常见的是绑定到一个集合,都可以用下图描述:

wpf databinding(3).jpg

注意缺省状况下是OneWay绑定。
同理,为了实现UI的自动更新,这个collection必须实现INotifyCollectionChanged接口,而collection里的每一个对象也要实现INotifyPropertyChanged接口。WPF提供的ObservableCollection<T>类已经实现了这个接口, 我们可以用它,也可以用List<T>和Collection<T>等。Sample








你可能感兴趣的:(bind)