如何在 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 的缺点=] 有。
如何在 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 的缺点=] 有。