C#探秘系列,八WPF数据绑定

WPF(Windrows Presentation Foundation)数据绑定提供了一种简单而持续的方式去与数据交互并将其呈现。元素可以通过各种形式的数据源以CLR(common language runtime)对象和xml对象如Button、ListBox、ListView等方式与数据联系起来。

数据绑定建立了在应用UI和业务逻辑之间的一种联系。一旦数据绑定成功,当数据改变值的时候,与数据绑定的元素会将其值自动显示出来。

以下将介绍如何构建数据绑定。

二、明确数据源

有多种方法去明确绑定的数据源。当你在同一源上绑定多个属性的时候,在父元素上使用DataContext属性行之有效。然而有时,在单个对象逐一声明绑定的数据源更为合适。如

<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>

三、明确值所在的路径

如果你绑定的数据源是一个对象,你可以用Path属性去明确所绑定的值。如果绑定的是xml数据,你可以使用XPath属性来明确绑定的值。在有些情况下,即使你使用xml对象用Path属性来实现绑定也许更便捷。比如,如果你想获取返回的XmlNode对象的Name属性,你可以使用Path属性而不是XPath属性。

<ListBox ItemsSource="{Binding}"
         IsSynchronizedWithCurrentItem="true"/>

四、Binding及BindingExpression

Binding类在声明Binding时是一个高级的类,它提供了很多可供你明确绑定特征的属性。与此相关的一个类——BindingExpression,它保持了源与目的对象之间的联系。一个Binding对象包含了可在一些binding表达式中传递的信息。

//make a new source
  MyData myDataObject = new MyData(DateTime.Now);      
  Binding myBinding = new Binding("MyDataProperty");
  myBinding.Source = myDataObject;
  myText.SetBinding(TextBlock.TextProperty, myBinding);

五、数据模板

Data Templating 允许数据以定义好的模板形式呈现:

<DataTemplate DataType="{x:Type src:AuctionItem}">
    <Border BorderThickness="1" BorderBrush="Gray"
            Padding="7" Name="border" Margin="3" Width="500">
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="86"/>
            <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>

            <Polygon Grid.Row="0" Grid.Column="0" Grid.RowSpan="4"
                     Fill="Yellow" Stroke="Black" StrokeThickness="1"
                     StrokeLineJoin="Round" Width="20" Height="20"
                     Stretch="Fill"
                     Points="9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7"
                     Visibility="Hidden" Name="star"/>

            <TextBlock Grid.Row="0" Grid.Column="1" Margin="0,0,8,0"
                       Name="descriptionTitle"
                       >Description:</TextBlock>
            <TextBlock Name="DescriptionDTDataType" Grid.Row="0" Grid.Column="2" 
                Text="{Binding Path=Description}" 
                />

            <TextBlock Grid.Row="1" Grid.Column="1" Margin="0,0,8,0"
                       Name="currentPriceTitle"
                       >Current Price:</TextBlock>
            <StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
                <TextBlock Text="$" />
                <TextBlock Name="CurrentPriceDTDataType" 
                    Text="{Binding Path=CurrentPrice}" 
                    />
            </StackPanel>
        </Grid>
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=SpecialFeatures}">
            <DataTrigger.Value>
                <src:SpecialFeatures>Color</src:SpecialFeatures>
            </DataTrigger.Value>
          <DataTrigger.Setters>
            <Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
            <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
            <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
            <Setter Property="BorderThickness" Value="3" TargetName="border" />
            <Setter Property="Padding" Value="5" TargetName="border" />
          </DataTrigger.Setters>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=SpecialFeatures}">
            <DataTrigger.Value>
                <src:SpecialFeatures>Highlight</src:SpecialFeatures>
            </DataTrigger.Value>
            <Setter Property="BorderBrush" Value="Orange" TargetName="border" />
            <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
            <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
            <Setter Property="Visibility" Value="Visible" TargetName="star" />
            <Setter Property="BorderThickness" Value="3" TargetName="border" />
            <Setter Property="Padding" Value="5" TargetName="border" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>