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

查看:72
本文介绍了绑定可以在没有INotifyPropertyChanged的情况下工作,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我们通常的操作方式:

This is how we do it normally:

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,那么您已经完全 负责在每个设置者中实施变更通知 需要将数据绑定到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.

请参阅: 查看全文

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