绑定在没有 INotifyPropertyChanged 的​​情况下工作,为什么? [英] Binding works without INotifyPropertyChanged, why?

查看:23
本文介绍了绑定在没有 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));
}

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

Now our property can be used by multiple elements in the view, e.g.:

<TextBox Text="{Binding Test, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding Test}" />

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

Changing value in TextBox will update content of TextBlock. As well as we can set value in the view model and view will update it automatically.

如果我们这样写视图模型

If we write view model like this

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

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

then the view is still working (e.g. changing value in TextBox will update TextBlock). Of course it's not possible to easily update Test value from view model anymore (no more event to rise). But my question is about view: Why view is able to work? Does it construct something more in background or is it a logic which checks for something?

推荐答案

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

[...] 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,则您完全负责在每个 setter 中实施更改通知需要绑定到 UI 的数据的属性.否则,更改不会如您预期的那样同步.

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.

参见:没有 INotifyPropertyChanged 的​​数据绑定

这篇关于绑定在没有 INotifyPropertyChanged 的​​情况下工作,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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