WPF中PropertyChanged UpdateSourceRigger的一种奇怪行为
我有这样一个实体:WPF中PropertyChanged UpdateSourceRigger的一种奇怪行为,wpf,binding,propertychanged,updatesourcetrigger,Wpf,Binding,Propertychanged,Updatesourcetrigger,我有这样一个实体: public class Person { public string Name { get; set; } public Person() { Name = "Godspeed"; } } 然后我在XAML中有三个文本框和一个按钮: <Window x:Class="WpfApplication19.MainWindow" xmlns="http://schemas.microsoft.com/win
public class Person
{
public string Name { get; set; }
public Person()
{
Name = "Godspeed";
}
}
然后我在XAML中有三个文本框和一个按钮:
<Window x:Class="WpfApplication19.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication19"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Person />
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}" />
<Button Click="Button_Click">Click</Button>
</StackPanel>
</Window>
它不会更新。所以我认为如果Person类实现INotifyPropertyChanged,这种行为是正常的,但是现在这个类没有实现接口,但是它也更新了接口。如果你有线索,请告诉我原因。谢谢。正如您所说,您只需实现
INotifyPropertyChanged
PropertyChanged
事件在您从code设置属性时使用,并且需要将此更改反映到您的UI(UI将包含PropertyChanged
事件,并且由于您的UpdateSourceTrigger
将更新UI)。另一方(从UI更改)不需要任何属性更改
,这就是您获得此行为的原因
就这样试试吧:
public class Person : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
/// <summary>
/// Property Changed Event
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Property Changed
/// </summary>
/// <param name="propertyName"></param>
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
}
公共类人员:INotifyPropertyChanged
{
#区域INotifyProperty更改成员
///
///属性更改事件
///
公共事件属性更改事件处理程序属性更改;
///
///财产变更
///
///
受保护的无效OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
#端区
私有字符串名称;
公共字符串名
{
获取{返回名称;}
设置
{
名称=值;
不动产变更(“名称”);
}
}
}
使用此代码,当您设置名称时,将触发
PropertyChanged
事件,因此相应地更新UI:)原因是PropertyDescriptor,请参阅以下线程,
有人问同样的问题:
这里有两个答案
我认为魔法在于装订系统的使用
PropertyDescriptor(SetValue)可能会引发一个ValueChanged-
PropertyDescriptor可能是共享的,而事件是在
按对象计算)
我不在微软,但我可以证实。如果PropertyDescriptor是 用于按原样更新值,然后进行相关更改 通知会自动传播 编辑
您可以通过命名
Person
DataContext对象来验证这一点
<Window.DataContext>
<local:Person x:Name="person"/>
</Window.DataContext>
更改三个文本框中任何一个的值后,您将进入事件处理程序OnPropertyChanged。它不仅适用于updatesourcetrigger=propertychanged,还适用于默认(失去焦点)值。除了@Meleak所说的之外,我想指出这是一种良好的行为。ui所做的任何更改都会传播到所有绑定目标。绑定引擎希望一次将此更改传播到所有控件。如果您通过代码进行更改,而未实现INotifyPropertyChanged,则从代码进行的更改根本不会反映出来。同样,对于具有相同绑定源的所有控件。所有控件都以同步方式与此类实现一起工作。因此,您的意思是,如果我设置propertychanged,UpdateRigger将自动更新UI,而不仅仅是对源实体进行更改?INotifyPropertyChanged接口只会触发从右后代码更改UI?就是这样,是的。基本上,UpdateRigger正在等待捕获PropertyChanged事件以刷新绑定。因为你没有在任何地方发射它,它不会触发任何更新。你明白我在这里说的意思了:PropertyChanged是用来说“嘿,UI,请刷新你自己,我变了!”:)
<Window.DataContext>
<local:Person x:Name="person"/>
</Window.DataContext>
public MainWindow()
{
InitializeComponent();
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(person);
PropertyDescriptor nameProperty = properties[0];
nameProperty.AddValueChanged(person, OnPropertyChanged);
}
void OnPropertyChanged(object sender, EventArgs e)
{
MessageBox.Show("Name Changed");
}