zoukankan      html  css  js  c++  java
  • 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








  • 相关阅读:
    【POJ】1067 取石子游戏(博弈论)
    【POJ】2348 Euclid's Game(扩欧)
    【POJ】1061 青蛙的约会 / 【BZOJ】1477(扩欧)
    【POJ】3090 Visible Lattice Points(欧拉函数)
    【BZOJ】2190 [SDOI2008]仪仗队(欧拉函数)
    【POJ】2115 C Looooops(扩欧)
    【BZOJ】1015 [JSOI2008]星球大战starwar(并查集+离线处理)
    [BZOJ4822][Cqoi2017]老C的任务
    [BZOJ1001][BeiJing2006]狼抓兔子
    [BZOJ1188][HNOI2007]分裂游戏
  • 原文地址:https://www.cnblogs.com/bear831204/p/1310585.html
Copyright © 2011-2022 走看看