一、WPF数据绑定的概要
数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程。 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改。 数据绑定可能还意味着如果视觉元素中数据的外部表现形式发生更改,则基础数据可以自动更新以反映更改。
例如:如果用户编辑 TextBox 元素中的值,则基础数据值会自动更新以反映该更改。
1. 数据绑定涉及到两个方面:
一个是绑定源,一个是绑定目标。绑定源即控件绑定所使用的源数据,绑定目标即数据显示的控件。
2. 对于绑定源,在WPF可以是以下四种:
•CLR对象:可以绑定到CLR类的公开的属性、子属性、索引器上。
•ADO.Net对象:例如DataTable、DataView等 。
•XML文件:使用XPath进行解析 。
•DependencyObject:绑定到其依赖项属性上,即控件绑定控件 。
对于绑定目标,必须是WPF中的DependencyObject,将数据绑定到其依赖项属性上。
二、 绑定的模式
1. 根据数据流的方向,WPF中的数据绑定分为以下四种:
OneWay 绑定:对源属性的更改会自动更新目标属性,但是对目标属性的更改不会传播回源属性。此绑定类型适用于绑定的控件为隐式只读控件的情况。
TwoWay 绑定:对源属性的更改会自动更新目标属性,而对目标属性的更改也会自动更新源属性。此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案 。
OneWayToSource 与 OneWay 相反;它在目标属性更改时更新源属性。
OneTime绑定:该绑定会导致源属性初始化目标属性,但不传播后续更改。
注释:如果无需监视目标属性的更改,则使用 OneWay 绑定模式可避免 TwoWay 绑定模式的系统开销。
大多数属性都默认为 OneWay 绑定,但是一些依赖项属性,通常为用户可编辑的控件的属性,如 TextBox 的 Text 属性和 CheckBox 的 IsChecked 属性,默认为 TwoWay 绑定。
如果要知道依赖项属性绑定在默认情况下是单向还是双向的编程方法可使用 GetMetadata 获取属性的属性元数据,然后检查 BindsTwoWayByDefault 属性的布尔值。
示例代码:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1" HorizontalAlignment="Center">
<Grid Name="GridTable" Height="360" Background="Silver">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="150"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Width="130" Height="25" Grid.Row="0" Grid.Column="0" Name="label1">TwoWay</Label>
<TextBox Width="150" Height="25" Grid.Row="0" Grid.Column="1" Name="textBox4" Text="{Binding ElementName=scrollBar1,Path=Value,Mode=TwoWay}" />
<Label Width="130" Height="25" Grid.Row="1" Grid.Column="0" Name="label2">OneWay</Label>
<TextBox Width="150" Height="25" Grid.Row="1" Grid.Column="1" Name="textBox1" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneWay}"/>
<Label Width="130" Height="25" Grid.Row="2" Grid.Column="0" Name="label3">OneWayToSource</Label>
<TextBox Width="150" Height="25" Grid.Row="2" Grid.Column="1" Name="textBox2" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneWayToSource}" />
<Label Width="130" Height="25" Grid.Row="3" Grid.Column="0" Name="label4">OneTime</Label>
<TextBox Width="150" Height="25" Grid.Row="3" Grid.Column="1" Name="textBox3" Text="{Binding ElementName=scrollBar1, Path=Value,Mode=OneTime}"/>
<ScrollBar Value="30" Minimum="0" Grid.RowSpan="4" Grid.Row="0" Grid.Column="2" Maximum="100" Name="scrollBar1" Width="18" Height="{Binding ElementName=GridTable,Path=Height}" />
</Grid>
</Page>
</div>
根据程序执行结果,我们可以得到以下结论:
对于OneWay绑定:在界面中显示的数据可以随数据源的值的变化而变化,但更改界面的数据不会影响到数据源。
对于TwoWay绑定:界面中显示的数据及数据源的数据可以双向显示及更新。
对于OneWayToSource绑定:初始时界面的数据为空;更改界面的数据可以影响数据源的值,但是更改数据源的值不会体现在界面上。
对于OneTime绑定:在界面中显示的为数据源的初始值,更改数据源的值的时候,不会更改界面的数据显示;更改界面的数据也不会影响到数据源的数据。
三、绑定目标值影响绑定源值条件
问题:绑定源的值是在您编辑文本的同时进行更新,还是在您结束编辑文本并将鼠标指针从文本框移走后才进行更新呢?或者在您需要更新的情况下在手动的更新呢?
1. UpdateSourceTrigger 属性是确定触发源更新的原因。
下图中右箭头的点演示 UpdateSourceTrigger 属性的角色:
TwoWay及OneWayToSource是由绑定目标到绑定源方向,若实现绑定目标的值更改影响绑定源的值方式,只需要设置相应控件绑定时的UpdateSourceTrigger的值,其值有三种:
PropertyChanged:当绑定目标属性更改时,立即更新绑定源。
LostFocus:当绑定目标元素失去焦点时,更新绑定源。
Explicit:仅在调用 UpdateSource 方法时更新绑定源。
注释:多数依赖项属性的UpdateSourceTrigger 值的默认值为 PropertyChanged,而 Text 属性的默认值为 LostFocus。
2. 示例
<Page x:Class="WpfDemo.Changed"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Changed">
<Grid Name="GridTable" Height="250" Background="Silver" Width="350">
<Grid.RowDefinitions>
<RowDefinition><