2011-11-18 63 views
6

我有一個功能,void Validate()一個單一的事件處理程序,包含我所有的驗證邏輯的窗口。實現多個控件與不同的事件處理程序委託

我不能簡單地註冊此作爲一個事件處理程序,因爲它不接受的事件處理程序委託所需的參數。另外不同類型的控件有不同的簽名,所以我不能只是Validate匹配一個簽名而忽略了內容。

這裏是什麼,我已經設置

txt1.TextChanged += Validate_TextChange; 
    password1.PasswordChanged += Validate_RoutedEvent; 
    txt2.TextChanged += Validate_TextChange; 

    txt3.TextChanged += Validate_TextChange; 
    password2.PasswordChanged += Validate_RoutedEvent; 
    txt4.TextChanged += Validate_TextChange; 


void Validate_RoutedEvent(object sender, RoutedEventArgs e) 
{ 
    ValidateOptions(); 
} 

void Validate_TextChange(object sender, TextChangedEventArgs e) 
{ 
    ValidateOptions(); 
} 

public void ValidateOptions() 
{ 
    //Actual validation here 
} 

這恰恰說明了兩個例子,更多的控制可以有更多的簽名,一個小例子。有沒有更好的方法讓所有的事件處理程序在我不關心傳遞參數的情況下調用函數?


編輯: 我喜歡喬恩提出的選項添加參數,完全無視。這的確解決了大部分問題,但只要我想直接調用這個函數,比如手動觸發驗證,然後我必須包括虛擬參數,以滿足編譯器。 ValidateOptions(this,new EventArgs())

Dan提出的使用匿名函數的建議可以處理這個問題,但在關聯事件處理程序時並不那麼幹淨。

似乎任何一種解決方案都不允許您將函數註冊爲事件處理函數,而忽略簽名,同時還保留調用函數而不創建僞參數的功能,但有多種方法可以非常接近。


編輯:

這裏是更新的例子實施喬恩對一般事件處理解決方案,但保持0參數的函數,可以直接調用

txt1.TextChanged += ValidationEvent; 
password1.PasswordChanged += ValidationEvent; 
txt2.TextChanged += ValidationEvent; 

txt3.TextChanged += ValidationEvent; 
password2.PasswordChanged += ValidationEvent; 
txt4.TextChanged += ValidationEvent; 


//Single event handler accepting EventArgs, which is the base class 
//for all more-specific event classes 
void ValidationEvent(object sender, EventArgs e) 
{ 
    //Ignores arguments and calls 0 argument ValidateOptions 
    ValidateOptions(); 
} 

//0 argument function that performs actual validation and can be called 
//directly from other functions without the need to pass in a fake sender 
//and eventargs parameter 
public void ValidateOptions() 
{ 
    //Actual validation here 
} 

回答

6

可以具有忽略參數一個方法:

public void ValidateOptions(object sender, EventArgs e) 
{ 
} 

編譯器將允許來自ValidateOptions方法組任何委託類型轉換的正常事件模式,例如以下第一個參數是sender,第二個參數是一些類型從EventArgs的。

+0

即使簽名無效'(對象,對象)'會實際工作。 –

+2

@ H.B。:真的 - 我寧願讓事情變得明顯:) –

+0

@Jon我喜歡這樣,它確實有效,但我後來意識到我忽略了原始問題中的部分用例(已更新) 。 Validate()函數還沒有這樣做的原因之一是因爲我想調用它來強制從其他函數進行驗證,並且通過這種方法我簡化了事件處理程序的使用,但是在直接調用它時必須使用假值。 – Eric

5

您可以使用lambda表達式來減少儘管在幕後,您爲包裝器編寫的代碼量仍然在創建包裝器方法來丟棄參數。

txt3.TextChanged += (s,e) => ValidateOptions(); 
password2.PasswordChanged += (s,e) => ValidateOptions(); 
txt4.TextChanged += (s,e) => ValidateOptions(); 
0

此處理程序提供了一個單一的回調框架控制和參數「E」被保留用於消費...

private static void EventHandlerSink(object sender, dynamic e) 
    { 

    } 
+0

當所有事件參數從'EventArgs'繼承時,沒有必要使用'dynamic',你只需要鬆開你在裝箱時留下的小界面。 –

相關問題