2014-10-28 70 views
0

我有一個用戶控件,我想一個事件成爲公衆:爲什麼我不能直接在C#中通過RoutedEventHandler

public event RoutedEventHandler CloseButtonClicked; 

但調度此事件,以下工作:

public MyUserControl() 
{ 
    InitializeComponent(); 

    closeButton.Click += CloseButtonClicked; 
} 

雖然以下確實工作:

public MyUserControl() 
{ 
    InitializeComponent(); 

    closeButton.Click += (sender, args) => CloseButtonClicked(sender, args); 
} 

這是爲什麼?

+1

你可以顯示'CloseButtonClicked'方法的聲明嗎? – 2014-10-28 13:29:46

+0

@EdChapel它在我的問題的第二行。 – 2014-10-28 14:07:05

+0

是否在'MyUserControl'中真正聲明瞭'CloseButtonClicked'事件(您嘗試使用它的同一個類)? – dewaffled 2014-10-28 14:26:54

回答

1

兩種情況之間的區別是當CloseButtonClicked事件被評估。

在第一個非工作示例中,事件字段的值在執行程序語句closeButton.Click += CloseButtonClicked;時進行評估。除非您已經將該字段設置爲某個有用的值,否則稍後在引發事件時不會發生任何事情。

在第二個工作示例中,在引發Click事件時評估事件字段的值。該語句聲明瞭一個匿名方法(通過lambda表達式),該方法在執行時調用存儲在CloseButtonClicked事件字段中的委託實例。所以只要該字段在事件發生前設置,那麼在執行closeButton.Click += (sender, args) => CloseButtonClicked(sender, args);語句時設置的字段不是並不重要。

請注意,即使第二條語句也會失敗,並帶有NullReferenceException,如果在引發Click事件時CloseButtonClicked事件字段尚未初始化。在引發事件時,應該首先檢查null(並且最好通過將值保存爲本地優先級來防止任何線程競爭條件),以防止出現這種情況。例如:

closeButton.Click += (sender, args) 
{ 
    RoutedEventHandler handler = CloseButtonClicked; 

    if (handler != null) 
    { 
     handler(sender, args); 
    } 
}; 

當然,上面的樣板常常被封裝成輔助方法(擴展或其他方式)。

0

這行不知道什麼時候會發生closeButton.Click要執行什麼:

closeButton.Click += CloseButtonClicked; 

要獲得實際的方法進去。您需要先設置CloseButtonClicked:

CloseButtonClicked += MyMethodWhichDoesSomething; 

現在創建方法MyMethodWhichDoesSomething並有引發事件(CloseButtonClicked(發件人,E);)

什麼這行做,實際上創建了這引起了事件的方法。 ..

closeButton.Click += (sender, args) => CloseButtonClicked(sender, args); 
相關問題