我有一个 Person 类:
public class Person : INotifyPropertyChanged
{
private string _name;
public string Name{
get { return _name; }
set {
if ( _name != value ) {
_name = value;
OnPropertyChanged( "Name" );
}
}
private Address _primaryAddress;
public Address PrimaryAddress {
get { return _primaryAddress; }
set {
if ( _primaryAddress != value ) {
_primaryAddress = value;
OnPropertyChanged( "PrimaryAddress" );
}
}
//OnPropertyChanged code goes here
}
我有一个地址类:
public class Address : INotifyPropertyChanged
{
private string _streetone;
public string StreetOne{
get { return _streetone; }
set {
if ( _streetone != value ) {
_streetone = value;
OnPropertyChanged( "StreetOne" );
}
}
//Other fields here
//OnPropertyChanged code goes here
}
我有一个 View 模型:
public class MyViewModel
{
//constructor and other stuff here
private Person _person;
public Person Person{
get { return _person; }
set {
if ( _person != value ) {
_person = value;
OnPropertyChanged( "Person" );
}
}
}
我有一个包含以下几行的 View :
<TextBox Text="{Binding Person.Name, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged />
<TextBox Text="{Binding Person.Address.StreetOne, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged />
当 View 加载时,这两个值都显示在文本框中。
对第一个文本框的更改将触发 MyViewModel 中的 OnPropertyChanged( "Person")
。太好了。
对第二个文本框 ("Person.Address.StreetOne")
的更改不会触发 MyViewModel 内的 OnPropertyChanged( "Person")
。这意味着它不调用 Person 对象的 SET 方法。不是很好。有趣的是调用了 Address 类中 StreetOne 的 SET 方法。
如何在 Person.Address.StreetOne
更改时调用 ViewModel 中 Person 对象的 SET 方法???
我是否需要展平我的数据,以便 SteetOne 在 Person 而不是 Address 中?
谢谢!
最佳答案
虽然向 ViewModel 添加“传递”属性是一个很好的解决方案,但它很快就会变得站不住脚。标准的替代方法是传播更改,如下所示:
public Address PrimaryAddress {
get => _primaryAddress;
set {
if ( _primaryAddress != value )
{
//Clean-up old event handler:
if(_primaryAddress != null)
_primaryAddress.PropertyChanged -= AddressChanged;
_primaryAddress = value;
if (_primaryAddress != null)
_primaryAddress.PropertyChanged += AddressChanged;
OnPropertyChanged( "PrimaryAddress" );
}
void AddressChanged(object sender, PropertyChangedEventArgs args)
=> OnPropertyChanged("PrimaryAddress");
}
}
现在更改通知从 Address 传播到 person。
编辑:将处理程序移至 c# 7 本地函数。
关于c# - 为嵌套属性实现 INotifyPropertyChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11870069/