通常,开发人员直接在要将数据绑定到的 UI 元素的 XAML 标记中声明绑定。 但是,还可以在代码中声明绑定。 本文介绍如何在 XAML 和代码中声明绑定。
先决条件
阅读本文之前,请务必熟悉标记扩展的概念和用法。 有关标记扩展的详细信息,请参阅 标记扩展和 WPF XAML。
本文不包括数据绑定概念。 有关数据绑定概念的讨论,请参阅 数据绑定概述。
在 XAML 中声明绑定
Binding 是标记扩展。 使用绑定扩展声明绑定时,声明由一系列语句组成,在 Binding
关键字之后并用逗号(,)分隔。 绑定声明中的子句可以按任意顺序排列,并且有许多可能的组合。 子句是 Name=值 对,其中 Name 是属性的名称 Binding , Value 是要为属性设置的值。
在标记中创建绑定声明字符串时,它们必须附加到目标对象的特定依赖属性。 以下示例演示如何使用绑定扩展绑定 TextBox.Text 属性,同时指定 Source 和 Path 属性。
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
上一个示例使用简单的数据类型 Person
。 以下代码片段是该对象的代码:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
您可以通过这种方式指定Binding类的大多数属性。 有关绑定扩展以及无法使用绑定扩展设置的属性列表 Binding 的详细信息,请参阅 绑定标记扩展(.NET Framework) 概述。
有关在 XAML 中创建绑定的示例,请参阅 如何创建数据绑定。
对象元素语法
对象元素语法是创建绑定声明的替代方法。 在大多数情况下,使用标记扩展或对象元素语法没有特别的优势。 但是,当标记扩展不支持你的方案(例如,当属性值为不存在类型转换的非字符串类型时),需要使用对象元素语法。
上一部分演示了如何与 XAML 扩展绑定。 以下示例演示如何执行相同的绑定,但使用对象元素语法:
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource myDataSource}" Path="Name"/>
</TextBlock.Text>
</TextBlock>
有关不同术语的详细信息,请参阅 XAML 语法详细信息(.NET Framework)。
多绑定 和 优先绑定
MultiBinding 并且 PriorityBinding 不支持 XAML 扩展语法。 因此,如果要在 XAML 中 MultiBinding 声明或 PriorityBinding 声明对象元素语法,则必须使用对象元素语法。
在代码中创建绑定
指定绑定的另一种方法是直接在代码中的对象上 Binding 设置属性,然后将绑定分配给属性。 以下示例演示如何在代码中创建 Binding 对象。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Make a new data source object
var personDetails = new Person()
{
Name = "John",
Birthdate = DateTime.Parse("2001-02-03")
};
// New binding object using the path of 'Name' for whatever source object is used
var nameBindingObject = new Binding("Name");
// Configure the binding
nameBindingObject.Mode = BindingMode.OneWay;
nameBindingObject.Source = personDetails;
nameBindingObject.Converter = NameConverter.Instance;
nameBindingObject.ConverterCulture = new CultureInfo("en-US");
// Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
' Make a new data source object
Dim personDetails As New Person() With {
.Name = "John",
.Birthdate = Date.Parse("2001-02-03")
}
' New binding object using the path of 'Name' for whatever source object is used
Dim nameBindingObject As New Binding("Name")
' Configure the binding
nameBindingObject.Mode = BindingMode.OneWay
nameBindingObject.Source = personDetails
nameBindingObject.Converter = NameConverter.Instance
nameBindingObject.ConverterCulture = New CultureInfo("en-US")
' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)
End Sub
前面的代码在绑定上设置以下内容:
- 数据源对象上属性的路径。
- 绑定的模式。
- 在本例中,数据源是表示人的简单的对象实例。
- 一个可选转换器,该转换器在分配给目标属性之前处理来自数据源对象的值。
绑定的对象为FrameworkElement或FrameworkContentElement时,可以直接在对象上调用SetBinding
方法,而不用使用BindingOperations.SetBinding。 有关示例,请参阅 “如何:在代码中创建绑定”。
上一个示例使用简单的数据类型 Person
。 下面是该对象的代码:
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
绑定路径语法
使用属性 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 实体进行转义:
使用
&
转义字符“&
”。使用
>
来转义结束标记“>
”。
此外,如果在属性中使用标记扩展语法描述整个绑定,则需要转义对 WPF 标记扩展分析器具有特殊意义的字符(使用反斜杠
\
)。反斜杠 (
\
) 是转义字符本身。等号 (
=
) 将属性名称与属性值分开。逗号 (
,
) 分隔属性。右大括号 (
}
) 是标记扩展的结束符。
绑定方向
使用 Binding.Mode 属性指定绑定的方向。 以下模式是绑定更新的可用选项:
绑定模式 | DESCRIPTION |
---|---|
BindingMode.TwoWay | 每当目标属性或源属性发生更改时,更新目标属性或属性。 |
BindingMode.OneWay | 仅在源属性更改时更新目标属性。 |
BindingMode.OneTime | 仅在应用程序启动时或 DataContext 发生更改时更新目标属性。 |
BindingMode.OneWayToSource | 在目标属性更改时更新源属性。 |
BindingMode.Default | 导致使用目标属性的默认值 Mode 。 |
有关详细信息,请参见 BindingMode 枚举。
以下示例演示如何设置 Mode 属性:
<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
若要检测源更改(适用于 OneWay 和 TwoWay 绑定),源必须实现适当的属性更改通知机制,例如 INotifyPropertyChanged。 有关详细信息,请参阅 “提供更改通知”。
对于 TwoWay 或 OneWayToSource 绑定,可以通过设置 UpdateSourceTrigger 属性来控制源更新的计时。 有关详细信息,请参阅 UpdateSourceTrigger。
默认行为
如果未在声明中指定,则默认行为如下所示:
创建一个默认转换器,该转换器尝试在绑定源值和绑定目标值之间执行类型转换。 如果无法进行转换,则默认转换器返回
null
。如果未设置 ConverterCulture,绑定引擎将使用
Language
绑定目标对象的属性。 在 XAML 中,该值默认为en-US
,或者继承自页面根元素(或任何元素)的值,如果页面已显式设置该值。只要绑定已有数据上下文(例如,来自父元素的继承数据上下文),并且该上下文返回的任何项或集合都适合绑定,而无需进一步修改路径,绑定声明根本就没有子句:
{Binding}
这通常是为数据样式指定绑定的方式,其中绑定对集合执行作。 有关详细信息,请参阅 将整个对象用作绑定源。默认值 Mode 因绑定的依赖属性而单向和双向变化。 您可以始终显式声明绑定模式,以确保绑定具有所需的行为。 通常,用户可编辑的控件属性(例如 TextBox.Text 和 RangeBase.Value)默认为双向绑定,但大多数其他属性默认为单向绑定。
默认UpdateSourceTrigger值因绑定依赖属性的不同而在PropertyChanged和LostFocus之间变化。 大多数依赖属性的默认值是
,而 属性的默认值为 < a0/>。