WPF 中 PropertyChanged UpdataSourceTrigger 的奇怪行为
我有一个像这样的实体:
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,但是当一个文本框更改时,它会修改源(Person)对象),但我们没有引发属性更改事件,但其余两个文本框自动更改。
单击按钮时,我们直接通过代码更新源,如下所示:
((Person)DataContext).Name = "Godspeed";
它不会更新。所以我的想法是,如果 Person 类实现了 INotifyPropertyChanged,这种行为是正常的,但现在该类没有实现该接口,但它也更新了接口。如果您有任何线索,请告诉我原因。谢谢。
I have an entity like this:
public class Person
{
public string Name { get; set; }
public Person()
{
Name = "Godspeed";
}
}
Then I have three textbox and a button in 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>
The weird thing is that, the entity "Person" doesn't implement the INotifyPropertyChanged, but when one text box is changed, it modifies the source(Person object), but we didn't raised the property changed event but the rest two textboxes automatically changed.
When the button clicks, we update the source directly by code like:
((Person)DataContext).Name = "Godspeed";
It doesn't update. So what I think is that if the Person class implement the INotifyPropertyChanged, this behavior is normal, but now the class doesn't implement the interface, but it update the interface too. Please info me the reason if you have some clue. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
原因是PropertyDescriptor,请参阅以下线程,
正在提出同样的问题: 数据绑定系统如何知道属性何时更改?
这是两个答案
编辑
您可以通过命名
Person
DataContext 对象并将以下代码添加到
MainWindow
ctor来验证这一点。一旦更改了三个 TextBox 中任何一个的值,您最终将得到在事件处理程序 OnPropertyChanged 中。
The reason is PropertyDescriptor, see the following thread,
the same question is being asked: How does the data binding system know when a property is changed?
Here is two of the answers
Edit
You can verify this by naming the
Person
DataContext objectand add the following code to the
MainWindow
ctorOnce you change the value on any of the three TextBoxes, you'll end up in the event handler OnPropertyChanged.
好吧,正如您所说,您只需实现
INotifyPropertyChanged
当您从代码设置属性并需要反映这一点时,将使用
PropertyChanged
事件更改您的 UI(UI 将触发PropertyChanged
事件,并且由于您的UpdateSourceTrigger
,UI 将更新)。另一侧(从 UI 更改)不需要任何PropertyChanged
,这就是为什么您会得到此行为只需尝试这样的操作:
使用此代码,当您设置名称时,
PropertyChanged< /code> 事件将被触发,因此相应地更新 UI :)
Well, as you said, you just have to implement
INotifyPropertyChanged
The
PropertyChanged
event is used when you set a property from code and need to reflect this change to your UI (UI will cath thePropertyChanged
event, and thanks to yourUpdateSourceTrigger
the UI will be updated). The other side (changing from UI) does not need anyPropertyChanged
, this is why you get this behaviorJust try it like that:
Using this code, when you set the Name, the
PropertyChanged
event will be fired and therefore update UI accordingly :)它不仅适用于 updatesourcetrigger=propertychanged,还适用于默认(失去焦点)值。除了@Meleak 所说的之外,我还想指出这是良好的行为。 ui 所做的任何更改都会传播到所有绑定目标。绑定引擎希望立即将此更改传播到所有控件。如果您通过代码进行更改,而不实现 INotifyPropertyChanged - 从代码中所做的更改根本不会反映出来。同样,对于具有相同绑定源的所有控件。所有控件都以与此类实现同步的方式工作。
It works not only with updatesourcetrigger=propertychanged, but with default (lost focus) value too. In addition to what @Meleak said, I want to point that it is good behaviour. Any changes made by ui are propagated to all binding targets. Binding engine wants to propagate this changes to all controls at once. If you make changes through code, and not implement INotifyPropertyChanged - changes made from code are not reflected at all. Again, for all controls with the same binding source. All controls works in the synchronized way with such implementation.