2016-03-06 55 views
0

是否有一种设置属性更改事件的优雅方法,其中包含在您不知道派生类中可包含哪些类型的数据时发生更改的数据?如何在不知道数据类型的情况下通过属性更改事件来传递数据?

例如:

// 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

使用对象作为您的类型或模仿通用事件处理程序作为灵感。 – kidshaw

+0

由于为公共属性引发了“PropertyChanged”,因此您的客户端不能直接向目标对象查询该属性的新值,而不是在事件中传递它? – dotNET

回答

1

由于PropertyChanged是针对公共属性产生的,因此您可以直接向目标对象查询属性的值,而不是在事件中传递它。例如,Windows窗体中的Resize事件(以及ClickDoubleClick等等)不包含宽度和高度信息。相反,您直接拨打Form.WidthForm.Height即可获取这些值。

这种情况不起作用的一种情况是,当您希望获取属性的旧值和新值时,旧值将在您的客户端收到关于更改的通知时被覆盖。 PropertyChanging模式提供了这个问题的一个优雅的解决方案。这个事件是在改变属性前立即引发的,因此客户可以在丢失其中一个之前读取旧值和新值。

+0

你知道吗,我非常关注通过改变的值的事件,我完全忘记了基础知识。我确实可以简单地为我的大部分情况做到这一点。我不打算将此标记为正确的答案,因为它不一定回答我的问题,但这是一个很好的解决方案。谢谢你提醒我常识大声笑 – Weikardzaena

相关问题