【问题标题】:Binding works without INotifyPropertyChanged, why?绑定在没有 INotifyPropertyChanged 的​​情况下工作,为什么?
【发布时间】:2017-04-19 17:58:13
【问题描述】:

这就是我们通常的做法:

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));
}

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

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

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

如果我们这样写视图模型

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

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

【问题讨论】:

  • 嗯..我不确定我是否理解你的例子。你说如果你不实现OnPropertyChanged视图仍然在工作(例如改变TextBox中的值会更新TextBlock)当然,视图会更新Source(这就是你在UpdateSourceTrigger)。但是在第二种情况下,如果您在视图模型中更改 Test 的值,则不会通知视图,并且您将不会在视图中看到该更新..
  • @Pikoh,我的问题是为什么用第二个视图模型替换第一个视图模型仍然可以用于视图。我只是不明白它工作背后的逻辑:我们没有完整的属性,setter 中没有任何内容,但它适用于视图没有问题:绑定到多个元素中的相同属性将正确跟踪其值的时间已更改。
  • 如果你想看一看这个神奇行为的完整工作示例,你可以看看我的问题here

标签: c# wpf binding inotifypropertychanged


【解决方案1】:

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

如果您正在实施 INotifyPropertyChanged,那么您完全可以 负责在每个 setter 中实施变更通知 需要将数据绑定到 UI 的属性。否则,该 更改不会像您期望的那样同步。

见:Data binding without INotifyPropertyChanged

【讨论】:

  • 好的,因此视图订阅每个此类绑定到ValueChanged 事件,并在更新源时自行发出通知。这解释了它是如何工作的,谢谢。
猜你喜欢
  • 2021-02-11
  • 2013-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多