绑定在没有INotifyPropertyChanged的情况下有效,为什么?

Sin*_*atr 5 c# wpf binding inotifypropertychanged

这是我们通常的做法:

public class ViewModel : INotifyPropertyChanged
{
    string _test;
    public string Test
    {
        get { return _test; }
        set
        {
            _test = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string property = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
Run Code Online (Sandbox Code Playgroud)

现在,我们的属性可以被视图中的多个元素使用,例如:

<TextBox Text="{Binding Test, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding Test}" />
Run Code Online (Sandbox Code Playgroud)

更改中的值TextBox将更新的内容TextBlock。我们可以在视图模型中设置值,然后视图将自动更新它。

如果我们这样写视图模型

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

视图仍在工作(例如,更改中的值TextBox将更新TextBlock)。当然,不可能再Test通过视图模型轻松更新值了(不再有事件发生)。但是我的问题是关于视图的:为什么视图可以工作?它是在后台构造更多东西还是逻辑来检查某些东西?

Leo*_*eon 6

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

并且,如果要实现INotifyPropertyChanged,则您有责任在每个属性的设置程序中实现更改通知,这些设置需要将数据绑定到UI。否则,更改将不会像您期望的那样同步。

请参阅:没有INotifyPropertyChanged的数据绑定