2016-03-06 66 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

相關問題