如何在 Derived 类 中提升 属性 更改?

How to Raise Property Changed in Derived Classes?

如何在 class B 中为 SomeProperty 筹集 PropertyChanged

此示例无法编译,因为 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:

你可以使用这个 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();
        }
    }
}

在我看来,这是迄今为止我所知道的最好的解决方案。

缺点是您可以像这样从另一个 class 筹集 PropertyChanged

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

以这种方式从其他 class 中提高 PropertyChanged 不是好的做法,所以我不担心这个缺点。

此解决方案的灵感来自 Thomas Levesque's answer here: Simple small INotifyPropertyChanged implementation

解决方案 2:

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

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

并调用派生中的方法class B:

public class B : A
{
    private object _someProperty;

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

缺点是你必须为你在对面创建的每个新基础 class 实现 RaisePropertyChanged 方法你避免了 解决方案 1[=48 的缺点=] 有。