更改通知
为了使源对象(数据源)的更改能够传播到目标(绑定数据的UI),源必须实现 INotifyPropertyChanged 接口。INotifyPropertyChanged 具有 PropertyChanged 事件,该事件通知绑定引擎源已更改,以便绑定引擎可以更新目标值。
数据源=>目标 的更改就只能用OneWay(只实现:数据源>>目标),TwoWay(实现:数据源>>目标,目标>>数据源),并且需要实现INotifyPropertyChanged接口。
目标=>数据源,只有使用TwoWay方式才可以修改数据源(且不需要实现INotifyPropertyChanged接口),这里事先把实体类用TwoWay的方式绑定到控件,那么在更改控件的时候,数据源自动会被更新,并不需要INotifyPropertyChanged的支持。但是如果两个控件绑定了同一个数据源,你希望在这里修改之后,可以自动通知另一个控件进行更改显示,那么请实现INotifyPropertyChanged。
更新数据源
使用TwoWay方式进行绑定后,一样可以禁用自动更新数据源,让数据源只在我们指定的情况下进行更新。例如我们这样做,以便在更新绑定数据源之前验证来自多个控件的用户输入。
若要禁用自动更新,需要在绑定时将UpdateSourceTrigger属性设置为Explicit。此设置影响使用相同 Binding 对象的所有绑定(例如,在使用继承的数据上下文时)。但是,在我们指定更新的时候必须为每个绑定单独更新源(每一个绑定目标的属性都要执行一次更新)。若要更新某一绑定,首先要实例化一个BindingExpression对象,再调用目标元素的 FrameworkElement.GetBindingExpression 方法,并传递目标元素的 DependencyProperty到这个方法,然后把返回值给BindingExpression对象。最后,可以使用BindingExpression对象调用 BindingExpression.UpdateSource 方法,便可以将目标元素的修改更新到数据源。以下是代码:
Xaml:
<TextBox x:Name="textBox1" Text="{Binding Test, Mode=TwoWay, UpdateSourceTrigger=Explicit}" />
<Button Content="Update" Click="Button_Click" />
C#
public class TestData
{
public String Test { get; set; }
}
TestData data;
public MainPage()
{
InitializeComponent();
data = new TestData { Test = "one" };
textBox1.DataContext = data;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
BindingExpression expression = textBox1.GetBindingExpression(TextBox.TextProperty);
MessageBox.Show("Before UpdateSource, Test = " + data.Test);
expression.UpdateSource();
MessageBox.Show("After UpdateSource, Test = " + data.Test);
}