为什么绑定更新没有实现INotifyPropertyChanged?

Muh*_*han 42 data-binding wpf xaml

我创建了一个ViewModel,并将其属性绑定到UI上的两个文本框.当我更改first的值并将焦点从文本框中移出但是我没有实现INotifyPropertyChanged 时,另一个文本框的值会发生变化.这是怎么回事?

以下是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>
Run Code Online (Sandbox Code Playgroud)

以下是我的ViewModel

class ViewModel
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Urb*_*Esc 51

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

很抱歉花了这么长时间回复,实际上你遇到了WPF的另一个隐藏方面,那就是WPF的数据绑定引擎将数据绑定到PropertyDescriptor实例,如果源对象是普通的CLR对象并且没有实现,它将包装source属性INotifyPropertyChanged接口.数据绑定引擎将尝试通过PropertyDescriptor.AddValueChanged()方法订阅属性更改事件.当目标数据绑定元素更改属性值时,数据绑定引擎将调用PropertyDescriptor.SetValue()方法将更改后的值传回源属性,并且它将同时引发ValueChanged事件以通知其他订阅者(在本例中,其他订阅者将是ListBox中的TextBlocks.

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

希望这会让事情变得清晰起来.

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

正如Hasan Khan所建议的,这是关于这个主题的一篇非常有趣的文章的另一个链接.

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

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

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

  • +1 我多年来一直在使用 WPF,但从未意识到这一点-也许您应该将其放在此处的“隐藏的 WPF 功能”主题中? (3认同)
  • 我已经用我认为有价值的所有相关信息更新了我的答案,以便快速浏览一下.另一天,另一个秘密暴露!我喜欢StackOverflow :) (2认同)
  • 因此,人们应该意识到,如果您不在 CLR 对象上实现 INotifyPropertyChanged ……您将导致内存泄漏。请参阅 http://www.cplotts.com/2009/04/14/wpf-memory-leaks/。 (2认同)