WPF_08_元素绑定

数据绑定是一种关系,告诉WPF从源对象提取一些信息来设置目标对象的属性,这些属性始终是 依赖属性 。源对象可以是任何内容,可以是另一个元素,可以是数据对象或自己创建的数据对象。

绑定元素

<Slider Name="slider" />
<TextBlock name="textBlock" Text="Test Text" FontSize="{Binding ElementName=slider, Path=Value}"/>

数据绑定表达式使用 XAML 标记扩展(因此具有花括号)。因为要创建 System.Windows.Data.Binding 类的一个实例,所以表达式以 Binding 开头。

之所以使用 Path 而不是 Property ,因为Path可能指向属性,也可能指向索引器,也可能指向属性的属性等等。
WPF不会引发异常来表明和数据绑定相关的问题。如果指定属性或元素不存在,不会收到任何指示,只是不能在目标属性中显示数据。当调试程序时,该信息显示在 Visual Studio 的 Output 窗口中。

绑定模式

当设置 Binding.Mode 属性时,WPF允许使用 System.Windows.Data.BindingMode 枚举值中的任何一个。

枚举值 说明
OneWay 当源变化时更新目标属性
TwoWay 当源变化时更新目标属性,并且当目标属性变化时更新源属性
OneTime 最初根据源属性值设置目标属性,只生效一次
OneWayToSource 与OneWay 相反,当目标变化时更新源属性
Default 默认方式,有可能是双向的(TextBox.Text),也有可能是单向的

OneWayToSource 常用于设置非依赖属性的属性。绑定表达式只能用于设置依赖属性,但 OneWayToSource 克服这一限制,但前提是提供数值的属性本身是依赖项属性。

代码创建绑定

Binding binding = new Binding();
binding.Source = slider;
binding.Path = new PropertyPath("Value");
binding.Mode = BindingMode.TwoWay;
textBlock.SetBinding(TextBlock.FontSize, bindig);

可以通过使用 BindingOperation 类的两个静态方法移出绑定,ClearBinding() 使用依赖项属性的引用作为参数; ClearAllBindings() 使用目标元素的引用作为参数。

可以使用静态方法 BindingOperations.GetBinding() 来获取 Binding 对象,需要提供两个参数:绑定元素 和 具有绑定表达式的属性。

// binding.Path 是绑定值
// binding.Path.Path 获取绑定属性的名称
Binding binding = BindingOperations.GetBinding(textBlock, TextBlock.FontSize);

BindingExpression expression = BindingOperations.GetBindingExpression(textBlock, TextBlock.FontSize);

绑定延迟

在某些特殊情况下,使用 Delay 属性,等待一段时间之后再提交更改。

<!--用户停止输入 500毫秒后更新源对象-->
<TextBox Text="{Binding ElementName=textBlock, Path=FontSize, Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged, Delay=500}" Name="textBlockFontSize"/>

绑定到非元素对象

当绑定到非元素对象时,不能使用 Binding.ElementName 属性,而是使用以下属性中的一个:

  • Source : 指向源对象的引用
  • RelativeSource : 这是引用,使用 RelateveSource 对象指向源对象。多用于编写控件模板以及数据模板。
  • DataContext : 如果没有设置 Source 或 RelativeSource 属性,WPF就从当前元素开始在元素树上向上查找,检查每个元素的 DataContext 属性,并使用第一个非空的 DataContext 属性。

Source 属性

Source属性为了进行绑定,需要具有数据对象。可以从资源中提取数据对象,可以通过代码生成数据对象。

<!--静态对象-->
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}"/>

<!--资源创建对象-->
<Window.Resources>
    <FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>
<TextBlock Text="{Binding Source={StaticResource CustomFont}, Path=Source}"/>

RelativeSource 属性

通过 RelativeSource 属性可根据相对于目标对象的关系指向源对象。RelativeSource 对象使用 FindAncestor 模式,该模式告知查找元素树直到发现 AncestorType 属性定义的元素类型。

<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>

FindAncestor 有4种模式:

名称 说明
Self 表达式绑定到同一元素的另一个属性上
FindAncestor 绑定到父元素,查找元素树直至发现期望的父元素。AncestorLevel 属性略过一定数量的特定元素
PreviousData 表达式绑定到数据绑定列表中的前一个数据项
TemplateParent 表达式绑定到应用模板的元素。当绑定位于控件模板或数据模板内部时才能工作

DataContext 属性

某些情况下,会将大量元素绑定到同一个对象,使用 FrameworkElement.DataContext 属性一次性定义绑定源会更清晰,也更灵活。

当绑定表达式中省略源信息时,WPF会检查元素的 DataContext 属性,如果为 null,会继续向上在元素树中查找第一个不为null的数据上下文。如果最终没找到,绑定表达式不会为目标属性应用任何值。

我的公众号

WPF_08_元素绑定

上一篇:字符素组


下一篇:winform 将子窗体显示在父窗体的TabControl控件上