是否有一种优雅的方式来设置属性更改事件,其中包括当您不知道派生类中可包含哪些类型的数据时更改的数据?
例如:
// I know I'm abusing the generics notation and this will not compile,
// but hopefully it will get my point across about what I'm trying to do.
class PropertyChangedEventArgs<T> : EventArgs
{
public string PropertyName { get; private set; }
public T Data { get; private set; }
public PropertyChangedEventArgs(string name, T data)
{
PropertyName = name;
Data = data;
}
}
public class Person
{
public event EventHandler<PropertyChangedEventArgs<T>> PropertyChanged = delegate { };
public int Age {
get;
protected set {
if (_age != value) {
_age = value;
OnPropertyChanged(new PropertyChangedEventArgs<int>("Age", _age));
}
}
} private int _age;
// More properties...
protected void OnPropertyChanged(PropertyChangedEventArgs<T> eventArgs)
{
EventHandler<PropertyChangedEventArgs<T>> handler = PropertyChanged;
if (handler != null) {
handler (this, PropertyChangedEventArgs<T>);
}
}
}
// Later we might want something like this, but we want to use the same event handler
public class Athlete : Person
{
public CholesterolNumbers Cholesterol {
get { return _cholesterol; }
protected set {
if (!_cholesterol.Equals(value)) {
_cholesterol = value;
// Same event, different data type:
OnPropertyChanged(new PropertyChangedEventArgs<CholesterolNumbers>("Cholesterol", _cholesterol));
}
}
} private CholesterolNumbers _cholesterol;
public struct CholesterolNumbers {
public int LDL;
public int HDL;
public int Trig;
public CholesterolNumbers(int ldl, int hdl, int trig)
{
LDL = ldl;
HDL = hdl;
Trig = trig;
}
}
}
是否有一种巧妙的方法,这样任何派生类都可以使用相同的EventHandler
,我们不必为我们稍后添加的每种类型编写一个全新的EventArgs
类?我看到了this solution一个非常相似的问题,但他们的方法仍然为每个单独命名的类型都有事件。我试图避免这种情况。
可以这样做吗?或者我应该重新考虑我的方法?
答案 0 :(得分:1)
由于为公共属性引发了PropertyChanged
,您可以直接在目标对象中查询属性的值,而不是在事件中传递它。例如,Windows窗体中的Resize
事件(以及Click
和DoubleClick
等)不会带有宽度和高度信息。相反,您可以直接致电Form.Width
和Form.Height
来获取这些值。
这种情况不起作用的一种情况是,您希望同时获取属性的旧值和新值,因为在客户端收到有关更改的通知时,旧值已被覆盖。 PropertyChanging
模式提供了这个问题的优雅解决方案。在更改属性之前,类会立即引发此事件,从而允许客户端在其中一个值丢失之前读取旧值和新值。