2016-12-05 108 views
3

这是我们如何做到这一点正常:绑定工作没有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)); 
} 

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

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

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

如果我们这样写

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

视图模型,然后的观点仍然是工作(例如在TextBox变化值将更新TextBlock)。当然,无法轻易更新视图模型中的Test值(不会再有更多的事件发生)。但我的问题是关于查看:为什么查看能够工作?它是否在后台构建了更多的东西,还是一种检查某些东西的逻辑?

+1

Hmm..i'm不知道我理解你的榜样。你说如果你没有实现'OnPropertyChanged',视图仍然有效(例如,在TextBox中改变值会更新TextBlock)_当然,视图更新了Source(这就是你在'UpdateSourceTrigger'时设置的原因)。但在第二种情况下,如果您在视图模型中更改了Test的值,则视图将不会被通知,并且您将不会在视图中看到该更新。 – Pikoh

+0

@Pikoh,我的问题是为什么要用第一个视图模型替换第二个还是可以的。我只是不理解其背后的逻辑是什么:我们没有完整的属性,setter中没有任何提升,但它对视图没有任何问题:绑定到多个元素中的相同属性将正确跟踪其值被改变。 – Sinatr

+0

如果你想看看这个神奇行为的完整工作示例,你可以看看我的问题[这里](https://stackoverflow.com/q/46803196/1977871)。 – VivekDev

回答

4

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

而且如果要实现INotifyPropertyChanged的,你完全 负责实施的 每一个二传手变更通知其需要绑定数据的属性到用户界面,否则, 更改将不会像您期望的那样同步。

参见:Data binding without INotifyPropertyChanged

+0

好的,所以查看每个绑定到'ValueChanged'事件的订阅,并在更新源时自动增加通知。这解释了它是如何工作的,谢谢。 – Sinatr

相关问题