绑定声明概述

本主题讨论声明绑定的不同方法。

先决条件

在阅读本主题之前,请务必熟悉标记扩展的概念和使用。 有关标记扩展的详细信息,请参阅标记扩展和 WPF XAML

本主题未涉及数据绑定概念。 有关数据绑定概念的讨论,请参阅数据绑定概述

在 XAML 中声明绑定

本部分介绍如何在 XAML 中声明绑定。

标记扩展使用

Binding 是标记扩展。 使用绑定扩展声明绑定时,声明包含一系列子句,这些子句跟在 Binding 关键字后面,并由逗号 (,) 分隔。 绑定声明中的子句可以按任意顺序排列,有多种可能的组合。 这些子句是 Name=Value 对,其中 Name 是 Binding 属性的名称,Value 是为该属性设置的值

在标记中创建绑定声明字符串时,必须将这些字符串附加到目标对象的特定依赖属性。 下面的示例演示如何使用绑定扩展并指定 SourcePath 属性来绑定 TextBox.Text 属性。

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=PersonName}"/>

可以通过这种方式指定 Binding 类的大多数属性。 有关绑定扩展以及使用绑定扩展无法设置的 Binding 属性列表的详细信息,请参阅绑定标记扩展概述。

对象元素语法

对象元素语法是创建绑定声明的替代方法。 在大多数情况下,使用标记扩展或对象元素语法没有特定的优势。 不过,如果标记扩展不支持你的方案,例如,当属性值是不存在任何类型转换的非字符串类型时,需要使用对象元素语法。

下面是对象元素语法和标记扩展使用的示例:

<TextBlock Name="myconvertedtext"
  Foreground="{Binding Path=TheDate,
                       Converter={StaticResource MyConverterReference}}">
  <TextBlock.Text>
    <Binding Path="TheDate"
             Converter="{StaticResource MyConverterReference}"/>
  </TextBlock.Text>
</TextBlock>

该示例通过使用扩展语法声明绑定来绑定 Foreground 属性。 Text 属性的绑定声明使用对象元素语法。

有关其他术语的详细信息,请参阅 XAML 语法详述

MultiBinding 和 PriorityBinding

MultiBindingPriorityBinding 不支持 XAML 扩展语法。 因此,在 XAML 中声明 MultiBindingPriorityBinding 时必须使用对象元素语法。

在代码中创建绑定

指定绑定的另一种方法是直接在代码中为 Binding 对象设置属性。 以下示例演示了如何在代码中创建 Binding 对象,并指定相应属性。 在此示例中,TheConverter 是实现 IValueConverter 接口的对象。

private void OnPageLoaded(object sender, EventArgs e)
{
    // Make a new source, to grab a new timestamp
    MyData myChangedData = new MyData();

    // Create a new binding
    // TheDate is a property of type DateTime on MyData class
    Binding myNewBindDef = new Binding("TheDate");

    myNewBindDef.Mode = BindingMode.OneWay;
    myNewBindDef.Source = myChangedData;
    myNewBindDef.Converter = TheConverter;
    myNewBindDef.ConverterCulture = new CultureInfo("en-US");

      // myDatetext is a TextBlock object that is the binding target object
    BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef);
    BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef);

    lbChooseCulture.SelectedIndex = 0;
}
 Private Sub OnPageLoaded(ByVal sender As Object, ByVal e As EventArgs)
     ' Make a new source, to grab a new timestamp
     Dim myChangedData As New MyData()

     ' Create a new binding
 ' TheDate is a property of type DateTime on MyData class
     Dim myNewBindDef As New Binding("TheDate")

     myNewBindDef.Mode = BindingMode.OneWay
     myNewBindDef.Source = myChangedData
     myNewBindDef.Converter = TheConverter
     myNewBindDef.ConverterCulture = New CultureInfo("en-US")

' myDatetext is a TextBlock object that is the binding target object
     BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef)
     BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef)

     lbChooseCulture.SelectedIndex = 0
 End Sub

如果要绑定的对象是 FrameworkElementFrameworkContentElement,可以直接对该对象调用 SetBinding 方法,而不是使用 BindingOperations.SetBinding。 有关示例,请参阅在代码中创建绑定

绑定路径语法

使用 Path 属性指定要绑定到的源值:

  • 在最简单的情况下,Path 属性值是要用于绑定的源对象的属性名称,如 Path=PropertyName

  • 在 C# 中,可以通过类似语法指定属性的子属性。 例如,子句 Path=ShoppingCart.Order 设置与对象或属性 ShoppingCart 的子属性 Order 的绑定。

  • 若要绑定到附加属性,请将附加属性置于括号中。 例如,若要绑定到附加属性 DockPanel.Dock,则语法为 Path=(DockPanel.Dock)

  • 可以在已应用索引器的属性名后面的方括号内指定属性的索引器。 例如,子句 Path=ShoppingCart[0] 将绑定设置为与属性的内部索引处理文本字符串“0”的方式对应的索引。 还支持嵌套索引器。

  • 可以在 Path 子句中混用索引器和子属性,例如 Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

  • 可以在索引器内使用多个由逗号 (,) 分隔的索引器参数。 可以使用括号指定每个参数的类型。 例如,可以使用 Path="[(sys:Int32)42,(sys:Int32)24]",其中 sys 将映射到 System 命名空间。

  • 如果源是集合视图,则可以使用斜杠 (/) 指定当前项。 例如,子句 Path=/ 设置与视图中当前项的绑定。 如果源是集合,则此语法指定默认集合视图的当前项。

  • 可以组合使用属性名和斜杠,以遍历作为集合的属性。 例如,Path=/Offices/ManagerName 指定源集合的当前项,源集合中包含的 Offices 属性也是一个集合。 它的当前项是一个包含 ManagerName 属性的对象。

  • 句点 (.) 路径也可以用于绑定到当前源。 例如,Text="{Binding}" 等效于 Text="{Binding Path=.}"

转义机制

  • 在索引器 ([ ]) 内部,脱字符号 (^) 用于对下一个字符进行转义。

  • 如果在 XAML 中设置 Path,还需要(使用 XML 实体)对 XML 语言定义专用的某些字符进行转义:

    • 使用 &amp; 对字符“&”进行转义。

    • 使用 &gt; 对结束标记“>”进行转义。

  • 此外,如果在属性中使用标记扩展语法描述整个绑定,需要(使用反斜杠 \)对 WPF 标记扩展分析器专用的字符进行转义:

    • 反斜杠 (\) 本身是转义字符。

    • 等号 (=) 将属性名与属性值分隔开。

    • 逗号 (,) 用于分隔属性。

    • 右大括号 (}) 是标记扩展的结尾。

默认行为

如果未在声明中指定默认行为,则默认行为如下所示。

  • 创建一个默认转换器,尝试在绑定源值和绑定目标值之间执行类型转换。 如果不能进行转换,默认转换器会返回 null

  • 如果未设置 ConverterCulture,绑定引擎会使用绑定目标对象的 Language 属性。 在 XAML 中,此属性默认为“en-US”,如果已显式设置了一个值,则从页面的根元素(或任何元素)继承该值。

  • 只要绑定已具有数据上下文(例如,来自父元素的继承数据上下文),并且该上下文返回的任何项或集合无需进一步修改路径即适用于绑定,则绑定声明可以不必使用任何子句:{Binding}。这通常是为数据样式指定绑定所用的方法,其中该绑定作用于某个集合。 有关详细信息,请参阅绑定源概述中的“整个对象用作绑定源”一节。

  • 默认 Mode 可能为单向,也可能为双向,具体取决于要绑定的依赖属性。 始终可以显式声明绑定模式,以确保绑定具有所需行为。 一般情况下,用户可编辑的控件属性(例如 TextBox.TextRangeBase.Value)默认为双向绑定,而其他大多数属性默认为单向绑定。

  • 默认 UpdateSourceTrigger 值可能为 PropertyChanged,也可能为 LostFocus,具体同样取决于绑定的依赖属性。 大多数依赖属性的默认值为 PropertyChanged,而 TextBox.Text 属性的默认值为 LostFocus

另请参阅