2011-08-22 114 views
1

我希望我的C#代碼在值賦給我的對象時調用一個事件。如何編寫觸發器?

我到底需要去做些什麼?

class MyClass { 

    ManualResetEvent mre; 

    public MyClass() { 
    mre = new ManualResetEvent(false); 
    Data = null; 
    } 

    public object Data { get; set; } 

    void DataSet(object sender, EventArgs e) { 
    Console.WriteLine("object Data has been set."); 
    mre.Set(); 
    } 

} 

代表似乎並不是我所需要的。一個事件,也許?如果是這樣的話,我會怎麼寫這樣的事件?

MyClass mc; 

void processA() { 
    mc = new MyClass(); 
    mc.Data = GetDataFromLongProcess(); 
} 

回答

5
private object data; 
public object Data { 
    get { return data;} 
    set { 
     if(value != data) { 
      data = value; 
      OnDataChanged(); 
     } 
    } 
} 
protected virtual void OnDataChanged() { 
    EventHandler handler = DataChanged; 
    if(handler != null) handler(this, EventArgs.Empty); 
} 
public event EventHandler DataChanged; 

然後勾任何代碼到事件DataChanged。例如:

MyClass mc = ... 
mc.DataChanged += delegate { 
    Console.WriteLine("new data! wow!"); 
}; 
+0

謝謝。我知道這很簡單。我只是有一個腦袋。 – jp2code

+0

DataChanged方法聲明中需要更改什麼,以便我可以編寫一個處理器方法,該方法使用自定義數據類型? (例如'if(handler!= null)handler(this,new MyEventArgs(Data));'(我已經寫了MyEventArgs'類,我不知道如何聲明'DataChanged'方法來實現它。 – jp2code

+1

@ jp2code你可以聲明它爲'public eventHandler' DataChanged;' – dlev

1

,你可以執行INotifyPropertyChanged(這或多或少是一個事件),或者你可以把你的類動作(觸發),並調用該方法,whenn屬性改變。

只是不要使用自動屬性,而是一個具體的setter,並從那裏調用你的事件/觸發器。

2

如果您希望在屬性設置爲觸發一個事件,你會做這樣的事情:

public event Action OnDataChanged; 

protected object _data = null; 
public object Data 
{ 
    get { return _data; } 
    set 
    { 
     _data = value; 
     if(OnDataChanged != null) 
      OnDataChanged(); 
    } 
} 

,那麼只需在連線事件處理程序到你的對象,像這樣:

mc = new MyClass(); 
mc.OnDataChanged += delegate() { Console.WriteLine("It changed!"); }; 
mc.Data = SomeValue(); 
+1

在大多數C#引用中,'OnFoo'是一個方法(通常是'protected virtual'),它調用*'event'命名爲'Foo' - 不是事件本身的名稱,當然這只是約定而不是規則,還要注意*嚴格地說*你應該在空檢查之前將字段捕獲到變量中,以避免線程邊緣條件,可能會導致一個'NullReferenceException' –

+0

好點,老實說,我沒有寫足夠的事件,已經違反了良好的慣例呢= D – Tejs

+0

其實,就*綁定*來說,有一個很好的理由來跟隨約定:'PropertyDescriptor'將*檢查*名爲'* Changed'(而不是'On * Changed')的事件並使用它來支持完整的數據綁定。這也適用於默認的'PropertyDescriptor' API的任何其他用途。 –

2

我認爲你正在以事件爲基礎的模式走上正軌。也看看觀察者模式(這是對.NET代表和骨子裏事件的基礎上,我的理解):

http://www.dofactory.com/Patterns/PatternObserver.aspx

但底線,作爲其他有用的答案爲止(格雷維爾先生的實施)表明,你將不得不有代碼IN讓它掛鉤。唯一的選擇是輪詢變化的價值,這對我來說很不好。

1

從概念上講,您應該在您的類中定義一個事件,並在您的屬性集塊中,使用必要的參數調用該事件以確定發生的事情。

1
public event SomeDelegateThatTakesIntAsParameter myEvent; 
void SetData(int data) 
{ 
    if(myEvent!= null) 
    myEvent(data) 
}