5

我已经INotifyPropertyChanged使用CallerMemberName

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
 if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

因此,这可以在任何属性的设置器中调用,因为OnPropertyChanged()它会在设置属性时通知属性更改事件。对于仅作为 getter 的属性而言,情况并非如此。例如,

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()DateOfBirth 工作正常,但要通知 Age 已更改,我应该记得OnPropertyChanged("Age")DateOfBirth. 我觉得这使得代码随着时间的推移难以维护。如果一个新属性依赖于年龄,那也需要在 DateOfBirth 的设置器中通知。有没有更好的方法可以在不调用 OnPropertyChanged("Age") 的情况下做到这一点?

4

2 回答 2

5

只要您的从属属性在同一个类中,您就可以使用 Poma 的方法,但如果从属属性在不同的类中,则使用该方法会变得更加困难。

在我看来,概念上正确的做法是添加一个 PropertyChanged 侦听器。

在这种情况下,这将类似于

在构造函数中:

this.PropertyChanged += new PropertyChangedEventHandler(SubPropertyChanged);

在外面:

private void SubPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "DateOfBirth")
    {
       OnPropertyChanged("Age");
    }
}

如果您在完全不同的地方有一个依赖属性,并且如果您不能再更改源类,这也可以工作。

于 2014-07-05T06:35:58.950 回答
-4

一种方法是定义您的属性并进行一些反射OnPropertyChanged以通知所有相关属性。您可能希望缓存属性以仅在类初始化程序中使用反射,因为反射非常慢。

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;
    }
}
于 2014-07-02T16:12:23.677 回答