如何提高派生类中已更改的属性?

时间:2019-02-20 14:56:26

标签: c# wpf events inotifypropertychanged propertychanged

如何在PropertyChanged课堂上为SomeProperty筹集B

此示例无法编译,因为无法通过这种方式访问​​PropertyChanged ...

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
}

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeProperty)))
        }
    }
}

1 个答案:

答案 0 :(得分:5)

解决方案1:

您可以使用以下RaisePropertyChangedExtension

public static class RaisePropertyChangedExtension
{
    public static void RaisePropertyChanged(this INotifyPropertyChanged @this, [CallerMemberName] string propertyName = null)
    {
        var declaringType = @this.GetType().GetEvent(nameof(INotifyPropertyChanged.PropertyChanged)).DeclaringType;
        var propertyChangedFieldInfo = declaringType.GetField(nameof(INotifyPropertyChanged.PropertyChanged), BindingFlags.Instance | BindingFlags.NonPublic);
        var propertyChangedEventHandler = propertyChangedFieldInfo.GetValue(@this) as PropertyChangedEventHandler;
        propertyChangedEventHandler?.Invoke(@this, new PropertyChangedEventArgs(propertyName));
    }
}

赞:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            this.RaisePropertyChanged();
        }
    }
}

我认为这是到目前为止我所知道的最好的解决方案。

缺点是您可以从另一个这样的班级筹集PropertyChanged

public class C
{
    public C(B b)
    {
        b.RaisePropertyChanged(nameof(b.SomeProperty));
    }
}

以这种方式从其他课程中提高PropertyChanged并不是一个好习惯,因此我对此并不担心。

此解决方案的灵感来自Thomas Levesque在这里的答案:Simple small INotifyPropertyChanged implementation

解决方案2:

您可以在基类RaisePropertyChanged中创建受保护的A

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

并在派生类B中调用该方法:

public class B : A
{
    private object _someProperty;

    public object SomeProperty
    {
        get => _someProperty;
        set
        {
            _someProperty = value;
            RaisePropertyChanged();
        }
    }
}

缺点是,您必须为正在创建的每个新基类实现RaisePropertyChanged方法,这样可以避免解决方案1 ​​的缺点。