为什么绑定更新而不实现 INotifyPropertyChanged? [英] Why does the binding update without implementing INotifyPropertyChanged?

查看:25
本文介绍了为什么绑定更新而不实现 INotifyPropertyChanged?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个 ViewModel 并将其属性绑定到 UI 上的两个文本框.当我更改 first 和 focus 的值离开文本框 时,另一个文本框的值会发生变化,但我没有实现 INotifyPropertyChanged.这是如何工作的?

I created a ViewModel and bound its property to two textboxes on UI. The value of the other textbox changes when I change the value of first and focus out of the textbox but I'm not implementing INotifyPropertyChanged. How is this working?

以下是 XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding Name}" />
        <TextBox Text="{Binding Name}" />
    </StackPanel>
</Window>

以下是我的 ViewModel

And following is my ViewModel

class ViewModel
{
    public string Name { get; set; }
}

推荐答案

我测试过,你是对的.现在我在网上搜索它,发现 这个.

I tested it, you are right. Now i searched for it on the web, and found this.

抱歉这么久才回复,实际上您遇到了另一个WPF的隐藏方面,那就是WPF的数据绑定引擎将数据绑定到包装了PropertyDescriptor的实例如果源对象是普通 CLR 对象并且未实现 INotifyPropertyChanged 接口,则为源属性.并且数据绑定引擎将尝试通过 PropertyDescriptor.AddValueChanged() 方法订阅属性更改事件.并且当目标数据绑定元素改变属性值时,数据绑定引擎会调用 PropertyDescriptor.SetValue() 方法将改变的值传回源属性,同时会引发 ValueChanged 事件通知其他订阅者(在这种情况下,其他订阅者将是 ListBox 中的 TextBlocks.

Sorry to take so long to reply, actually you are encountering a another hidden aspect of WPF, that's it WPF's data binding engine will data bind to PropertyDescriptor instance which wraps the source property if the source object is a plain CLR object and doesn't implement INotifyPropertyChanged interface. And the data binding engine will try to subscribe to the property changed event through PropertyDescriptor.AddValueChanged() method. And when the target data bound element change the property values, data binding engine will call PropertyDescriptor.SetValue() method to transfer the changed value back to the source property, and it will simultaneously raise ValueChanged event to notify other subscribers (in this instance, the other subscribers will be the TextBlocks within the ListBox.

如果您正在实施 INotifyPropertyChanged,则您完全有责任在需要将数据绑定到 UI 的属性的每个 setter 中实施更改通知.否则,更改将不会如您预期的那样同步.

And if you are implementing INotifyPropertyChanged, you are fully responsible to implement the change notification in every setter of the properties which needs to be data bound to the UI. Otherwise, the change will be not synchronized as you'd expect.

希望这能让事情变得更清楚.

Hope this clears things up a little bit.

所以基本上你可以做到这一点,只要它是一个普通的 CLR 对象.非常整洁但完全出乎意料 - 过去几年我做了一些 WPF 工作.你永远不会停止学习新事物,对吧?

So basically you can do this, as long as its a plain CLR object. Pretty neat but totally unexpected - and i have done a bit of WPF work the past years. You never stop learning new things, right?

根据 Hasan Khan 的建议,这里是 另一个链接,指向关于这个主题的一篇非常有趣的文章.

As suggested by Hasan Khan, here is another link to a pretty interesting article on this subject.

注意这仅在使用绑定时有效.如果您从代码更新值,则不会通知更改.[...]

Note this only works when using binding. If you update the values from code, the change won't be notified. [...]

WPF 在绑定时使用轻得多的 PropertyInfo 类.如果显式实现 INotifyPropertyChanged,则 WPF 所需要做的就是调用 PropertyInfo.GetValue 方法以获取最新值.这比获取所有描述符要少得多.描述符最终的成本是属性信息类内存的 4 倍.[...]

WPF uses the much lighter weight PropertyInfo class when binding. If you explicitly implement INotifyPropertyChanged, all WPF needs to do is call the PropertyInfo.GetValue method to get the latest value. That's quite a bit less work than getting all the descriptors. Descriptors end up costing in the order of 4x the memory of the property info classes. [...]

实施 INotifyPropertyChanged 可能是一项相当乏味的开发工作.但是,您需要根据 WPF 应用程序的运行时占用空间(内存和 CPU)权衡该工作.自己实现 INPC 将节省运行时 CPU 和内存.

Implementing INotifyPropertyChanged can be a fair bit of tedious development work. However, you'll need to weigh that work against the runtime footprint (memory and CPU) of your WPF application. Implementing INPC yourself will save runtime CPU and memory.

更新这个,因为我仍然不时从这里得到评论和投票,所以它显然仍然相关,即使我自己已经有一段时间没有使用 WPF 了.但是,如评论中所述,请注意这可能会导致 内存泄漏.据说它也很注重反射的用法,这也被提到过.

Updating this, since i still get comments and upvotes now and then from here, so it clearly is still relevant, even thouh i myself have not worked with WPF for quite some time now. However, as mentioned in the comments, be aware that this may cause memory leaks. Its also supposedly heavy on the Reflection usage, which has been mentioned as well.

这篇关于为什么绑定更新而不实现 INotifyPropertyChanged?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆