问题
I have the INotifyPropertyChanged
implemented using CallerMemberName
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
So this could be called in the setter of any property as - OnPropertyChanged()
which would notify property changed event whenever it is being set. This is not the case for a property a getter only. For example,
private DateTime _dob;
public DateTime DateOfBirth
{
get
{
return _dob;
}
private set
{
_dob = value;
OnPropertyChanged();
OnPropertyChanged("Age");
}
}
public int Age
{
get
{
return DateTime.Today.Year - _dob.Year;
}
}
OnPropertyChanged()
works fine for DateOfBirth, but to notify Age changed, I should remember to call OnPropertyChanged("Age")
within the setter of DateOfBirth
. I feel this makes the code difficult to maintain over time. If a new property depends on Age, that also needs to be Notified in the setter of DateOfBirth. Is there a better way to do this without calling OnPropertyChanged("Age")?
回答1:
As long as your dependent property is in the same class you can use Poma's approach but if the dependent properties are in different classes its getting harder with that approach.
In my opinion the conceptually right thing to do would be to add a PropertyChanged listener.
In this case that would be something like
In the constructor:
this.PropertyChanged += new PropertyChangedEventHandler(SubPropertyChanged);
And outside:
private void SubPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "DateOfBirth")
{
OnPropertyChanged("Age");
}
}
This then also works if you have a dependent property somewhere completely different and also if you cannot change your source class anymore.
回答2:
One way to do that is to define your attribute and do some reflection in OnPropertyChanged
to notify all dependent properties. You may want to cache attributes to use reflection only in class initializer because reflection is pretty slow.
private DateTime _dob;
public DateTime DateOfBirth
{
get
{
return _dob;
}
private set
{
_dob = value;
OnPropertyChanged();
}
}
[DependsOnProperty("DateOfBirth")]
public int Age
{
get
{
return DateTime.Today.Year - _dob.Year;
}
}
来源:https://stackoverflow.com/questions/21776439/wpf-notify-propertychanged-for-a-get-property