数据绑定方向与INotifyPropertyChanged
一、数据绑定方向
Binding类的Mode属性可以指定数据绑定的方向:
官方文档:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.data.bindingmode?view=netframework-4.8
枚举值 | 说明 |
---|---|
TwoWay | 双向更新,适用于可编辑的表单或其他完全交互式 UI 方案。 |
OneWay | 在源属性更改时更新(控件)目标属性,如果无需监视目标属性的更改,则使用 OneWay 绑定模式可避免 TwoWay 绑定模式的系统开销。 |
OneTime | OneWay的一种简化形式,在应用程序启动或数据上下文更改时,更新目标属性。 |
OneWayToSource | 与OneWay绑定相反,在(控件)目标属性更改时,更新源属性。 |
Default | 不同的依赖属性的默认值都不同。 |
Binding类的UpdateSourceTrigger属性指示更新绑定源的时机,可使用 DependencyProperty.GetMetadata 获取属性的元数据即默认数据,然后检查该属性的值 FrameworkPropertyMetadata.DefaultUpdateSourceTrigger。
官方文档:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.data.updatesourcetrigger?view=netframework-4.8
枚举值 | 说明 |
---|---|
Default | 不同的依赖属性的默认值都不同。大多数依赖项属性默认值为PropertyChanged,而Text属性的默认值为LostFocus。 |
PropertyChanged | 当绑定目标属性发生改变时,立即更新绑定源。 |
LostFoucs | 当绑定目标失去焦点时,才会更新绑定。 |
Explicit | 当调用UpdateSource()方法时才更新绑定源。 |
在MainWindows.xaml.cs创建Teacher类,代码如下:
public partial class MainWindow : Window
{
Teacher teacher;
public MainWindow()
{
teacher = new Teacher();
teacher.Name = "张三";
InitializeComponent();
//设置绑定数据的上下文,为默认数据源
DataContext = teacher;
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
//打印数据源的值,观察是否发生改变
Console.WriteLine(teacher.Name);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
teacher.Name = "改变啦";
}
}
public class Teacher
{
private String name;
public String Name
{
get { return name; }
set { name = value; }
}
}
在XAML界面增加TextBox和Button控件,代码如下:
<Grid>
<TextBox x:Name="textBox" Text="TextBox" TextChanged="TextBox_TextChanged"/>
<Button x:Name="button" Content="设置数据源的值" Click="Button_Click"/>
</Grid>
1. OneWayToSource
textBox控件内容发生改变时,teacher属性的Name发生改变
2. OneWay
将teacher属性的Name展示于textBox控件内,但是当Name发生改变时,textBox控件内容无变化。若实现同步更新,需配合INotifyPropertyChanged,见第二部分描述
3. TwoWay
通过编辑textBox控件或teacher对象的Name属性,都可使textBox内容发生变化。若实现同步更新,需配合INotifyPropertyChanged,见第二部分描述
二、INotifyPropertyChanged
INotifyPropertyChanged 是位于System.ComponentModel命名空间内的一个接口,定义了一种通用的机制,通过该机制可以使对象在其属性发生更改时通知观察者。源对象继承该接口,有两种使用方法,第一种在展示如下:
public class Teacher : INotifyPropertyChanged
{
private String name;
public String Name
{
get {
return name;
}
set {
name = value;
//第一种用法,内写参数
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
//第一种用法,令入参可为空
protected virtual void OnPropertyChanged(String propertyName="")
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
}
第二种用法在OnPropertyChanged()内不填入参,写函数OnPropertyChanged([CallerMemberName]String propertyName=“”),[CallerMemberName]允许获取方法调用方的方法或属性的名称,可参考官方文档,第二种方法展示如下:
public class Teacher : INotifyPropertyChanged
{
private String name;
public String Name
{
get {
return name;
}
set {
name = value;
//第二种用法在OnPropertyChanged()内不填入参
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
//入参为 [CallerMemberName]String propertyName=""
protected virtual void OnPropertyChanged([CallerMemberName]String propertyName="")
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ));
}
}
总结
- OneWay与TwoWay的绑定,基础数据必须实现INotifyPropertyChanged
- TwoWay与OneWayToSource的绑定,通过设置UpdateSourceTrigger属性控制目标到源的更新
- ?.Invoke在此处表示判断入参是否为空,为空则不执行,若不为空则调用事件PropertyChanged( this, new PropertyChangedEventArgs( propertyName ))