书名:WPF专业编程指南
作者:李应保
出版社:电子工业出版社
出版时间:2010-01
ISBN:9787121100116
数据绑定
一、DataContext
- DataContext是.NET 1.0就有的机制,WPF不仅保留了这一概念,而且由于相关对象(Dependency Object)和相关属性的引入,使得DataContext的功能更加强大。
DataContext是FrameworkElement类中的一个相关属性,如果有大量数据来源于同一种数据结构,如数据库的同一个表(database table),或同一个类(class)等情况下,那么使用DataContext就非常方便;如果源对象之间没啥关系,DataContext就不会有什么优势。
下面是一个在XAML中设定DataContext属性的例子:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBinding" Height="300" Width="300" >
<StackPanel>
<ScrollBar Name="scroll" Orientation ="Horizontal " Margin ="24"
Maximum ="100" LargeChange ="10" SmallChange ="1"/>
<TextBox Name="scrollValue1" Height ="20" Width ="200"
HorizontalAlignment ="Center" DataContext="{Binding
ElementName=scroll}" Text ="{Binding Path=Value, Mode=TwoWay}"/>
</StackPanel >
</Window>
我们设定的只是scrollValue1这一个控件的DataContext,可以看出设定DataContext的语法:
DataContext="{Binding ElementName=scroll}"
即使用XAML的绑定扩展。
- 在上面这个例子中,直接设定TextBox的DataContext属性。
对于单个UI元素,使用DataContext不仅没有优势,而且还有点烦琐。原来我们只要用一个绑定扩展,现在却要用两个!
如果有多个控件绑定到同一个数据结构或一个控件上,就可以看到使用DataContext的方便之处:
<Window x:Class="DataBinding.MultipleContextBinding"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MultipleContextBinding" DataContext="{Binding
ElementName=scroll}" Height="373" Width="337">
<StackPanel>
<ScrollBar Name="scroll" Orientation ="Horizontal "
Margin ="24" Maximum ="100"
LargeChange ="10" SmallChange ="1"/>
<Label Height ="30">One way binding:</Label>
<TextBox Name="scrollValue1" Height ="20" Width ="200"
HorizontalAlignment ="Center" Text ="{Binding Path=Value,
Mode=OneWay}"/>
<Label Height ="30">Two way binding:</Label>
<TextBox Name="scrollValue2" Height ="20" Width ="200"
HorizontalAlignment="Center" Text ="{Binding Path=Value,
Mode=TwoWay}"/>
<Label Height ="30">One time binding:</Label>
<TextBlock Name="scrollValue3" Height ="20" Width ="200"
HorizontalAlignment ="Center" Text ="{Binding Path=Value,
Mode=OneTime}"/>
<Label Height ="30">One way to source:</Label>
<TextBox Name="scrollValue4" Height ="20" Width ="200"
HorizontalAlignment ="Center" Text ="{Binding Path=Value,
Mode=OneWayToSource}"/>
<Label Height ="30">Default:</Label>
<TextBlock Name="scrollValue5" Height ="20" Width ="200"
HorizontalAlignment ="Center" Text ="{Binding Path=Value,
Mode=Default}"/>
</StackPanel>
</Window>
- 这个例子是对本章开始时例子的改写,这里把Window的相关属性DataContext设为scroll1,这样,所有绑定到ScrollBar的控件(TextBlock)都可以在Binding的大括号中省掉ElementName=scroll。
这里所用的机制是WPF中相关属性的传递:包容器类的相关属性被传递到其中的子类。
由于在视觉树的任何一个父节点上设定DataContext,都可以传递到其中的子类,所以我们设定StackPanel的DataContext属性,其结果是一样的:
<StackPanel DataContext="{Binding ElementName=scroll}">
当然如果你不使用DataContext,则也可以在每个元素中加入ElementName。
二、控制绑定时刻
当用户在界面上输入数据的时候,你可能希望自己能够控制用户的输入传递到源对象的时间。
比如,当用户单击CheckBox时,希望CheckBox的状态变化立即传递到所绑定的对象;
当用户在TextBox中输入字符串时,往往不必要立即把用户的输入传递到所绑定的对象,用户可能对输入的字符串进行修改,这时我们希望等到输入焦点移到下一个控件上时,再把用户的输入传递到所绑定的源对象。换句话说,数据的传递发生在这个TextBox失去输入焦点的那一刻。-
WPF数据绑定允许你自由地控制数据传递发生的时刻,控制绑定对象间数据传递发生的时刻是由UpdateSourceTrigger来完成的。表11-1列出了UpdateSourceTrigger的可能取值及其功能。
表11-1 UpdateSourceTrigger的值
可以在XAML中设置UpdateSourceTrigger,例如:
<TextBlock Name="scrollValue" Height ="20" Width ="200"
HorizontalAlignment ="Center" Text ="{Binding Path=Value,
Mode=Default UpdateSourceTrigger=LostFocus}"/>
