2013-02-20 61 views
21

我有一個用戶控件在與Web服務通信後引發事件。父級在引發時處理此事件。什麼我認爲將是正確的做法將傳遞從webservice返回的對象作爲eventargs的父母?如何傳遞EventArgs中的對象

如果這是正確的方法,我似乎無法找到如何這樣做的說明。

用戶控件

public event EventHandler LoginCompleted; 

再到後來的服務回報BIZ對象後:

if (this.LoginCompleted != null) 
     { 
      this.LoginCompleted(this, new EventArgs() //this is where I would attach/pass my biz object no?); 
     } 

家長

ctrl_Login.LoginCompleted += ctrl_Login_LoginCompleted; 
....snip.... 
void ctrl_Login_LoginCompleted(object sender, EventArgs e) 
    { 
     //get my object returned by login 
    } 

所以我的問題是什麼將批准的方法獲取用戶對象回到父?創建一個一切都可以訪問並放在那裏的屬性類?

回答

35

你將不得不使用EventHandler<T>聲明你的事件,其中T是你的班級,從EventArgs派生:

public event EventHandler<LoginCompletedEventArgs> LoginCompleted; 

LoginCompletedEventArgs看起來是這樣的:

​​

用法是這樣的:

private void RaiseLoginCompleted(YourBusinessObject businessObject) 
{ 
    var handler = LoginCompleted; 
    if(handler == null) 
     return; 

    handler(this, new LoginCompletedEventArgs(businessObject)); 
} 

請注意我是如何實施RaiseLoginCompleted的。這是提高事件的線程安全版本。我刪除了可能發生在競爭條件情況下的一個可能的NullReferenceException,其中一個線程想要引發事件,而另一個線程在if檢查後但在實際調用處理程序之前取消最後一個處理程序。

+0

這就是票!讓我執行並馬上回來。 – GPGVM 2013-02-20 10:54:11

+0

你會想要該屬性是除了只讀以外的任何東西嗎? IE從來沒有一種情況下,你想要設置它比通過構造函數的任何其他方式? – GPGVM 2013-02-20 11:00:06

+0

@ user1278561:有兩種可能的情況:(1)引發事件並創建實例的類想要更改該屬性。這不會發生,因爲實例沒有保存在任何地方,它直接傳遞給處理程序。 (2)事件處理程序想要更改該屬性。你不想這樣做,因爲事件的其他訂閱者現在將獲得與培養班級提供的實例不同的實例。 – 2013-02-20 11:08:57

3

那麼,你可以做所有的事情,或者你可以定義一個委託作爲你的EventHandler,並在它的簽名中定義你的屬性。

例如: public delegate void MyEventEventHandler(int prop1,string prop2,object prop3 ...);

公共事件MyEventEventHandler MyEvent;

+1

更清潔,更高效恕我直言 – 2017-11-07 14:57:07