首先,您可以简化RaisePropertyChanged
这种方式:
public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
所以你不需要写RaisePropertyChanged("Description")
,而只需要:RaisePropertyChanged()
,并且propertyName
自动注入。如果您经常重构,那就太棒了:您不必面对记住整个解决方案中所有“标题”和“描述”字符串的噩梦 :)
其次,如果有的话BaseClass
,PropertyChangedEvent
可以在里面收听MyClassViewModel
。
myClassBase.PropertyChanged += (s, e) => { RaisePropertyChanged(e.PropertyName); };
但是,如果你不myClassBase
立即在 的构造函数中注入MyClassViewModel
,或者如果myClassBase
可以在某个时候改变,事情会变得有点复杂。
您MyClassViewModel
还必须实施INotifyPropertyChanging
:
public event PropertyChangingEventHandler PropertyChanging;
public void RaisePropertyChanging([CallerMemberName] string propertyName = null)
{
PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName));
}
您还必须为myClassBase
:
public BaseClass myClassBase
{
get { return _myClassBase; }
set
{
RaisePropertyChanging();
_myClassBase = value;
RaisePropertyChanged();
}
}
private BaseClass _myClassBase;
然后,您只需要以下代码:
public MyClassViewModel()
{
PropertyChanging += OnPropertyChanging;
PropertyChanged += OnPropertyChanged;
}
private void OnPropertyChanging(object sender, PropertyChangingEventArgs e)
{
if (e.PropertyName != nameof(MyClassViewModel.myClassBase))
return; //or do something with the other properties
if (myClassBase == null)
return;
myClassBase.PropertyChanged -= OnMyBaseClassPropertyChanged;
}
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != nameof(MyClassViewModel.myClassBase))
return; //or do something with the other properties
if (myClassBase == null)
return;
myClassBase.PropertyChanged += OnMyBaseClassPropertyChanged;
}
private void OnMyBaseClassPropertyChanged(object sender, PropertyChangedEventArgs e)
{
RaisePropertyChanged(e.PropertyName);
}
NB:我用的是C#-6.0nameof()
操作符,希望你能用,简直太棒了!
编辑:
在这里,您有一个简单的测试方法来演示正确的功能:
[TestMethod]
public void ChildClassPropertyChanged()
{
var bc = new BaseClass();
var c = new MyClassViewModel();
bc.Title = "t1";
c.myClassBase = bc;
Assert.AreEqual("t1", c.Title);
c.Title = "t2";
Assert.AreEqual("t2", c.Title);
c.myClassBase.Title = "t3";
Assert.AreEqual("t3", c.Title);
c.myClassBase = new BaseClass();
bc.Title = "t4";
Assert.AreEqual(null, c.Title);
c.myClassBase.Title = "t5";
Assert.AreEqual("t5", c.Title);
}
请记住,如果您null
myClassBase
在属性的 getter 和 setter 中设置 a ,代码会抛出 a NullReferenceException
。也许你应该这样修改它:
public string Title
{
get
{
return myClassBase?.Title;
}
set
{
if (myClassBase != null)
myClassBase.Title = value;
RaisePropertyChanged();
}
}