2014-03-19 42 views
1

我一直在修補事件以更好地理解它們在非常普遍的情況下的使用。我很驚訝地發現以下內容,所以我可能會朝着錯誤的方向前進...我正在做的事情的本質是在單擊按鈕時將按鈕更改爲隨機顏色:Is + = delegate {}將自定義事件附加到UI控件事件的正確方法是什麼?

Windows窗體

public Form1()  
{ 

ColorChanges KK = new ColorChanges(); 

KK.ColorEventHandler += handle_ColorChanges; 

button1.Click += delegate { KK.ChangeColor(button1); }; 

} 

事件類

class ColorChanges 
{ 

    *... properties & constructor* 

    public void ChangeColor(object sender) 
    { 
    *... randomly assign color to ColorEventArgs* 
    } 

    protected virtual void onColorEvent(object sender, ColorEventArgs e) 
    { 
     EventHandler<ColorEventArgs> ceh = ColorEventHandler; 
     { 
     if (ceh != null) 
     { 
     ceh(sender, e)    
     } 
    } 
    } 

    public event EventHandler<ColorEventArgs> ColorEventHandler; 
} 

自定義事件參數

public class ColorEventArgs : EventArgs 
{ 
    public Color xColor { get; set; } 
} 

事件哈ndler

public void handle_ColorChanges(object sender, ColorEventArgs e) 
{ 
    if (sender is Button) 
     { 
     var ButtonSender = (Button)sender; 

     ButtonSender.BackColor = e.xColor; 
     } 
} 

所以編輯的問題是:

在使用的事件處理程序(TEventArgs)的委派有用嗎? MS文檔指出語法像

button1.Click += new EventHandler<AutoRndColorEventArgs>(handle_ColorChanges); 

是正確的,但不會達到我的代碼隨機選擇一種顏色,一個錯誤

「不超載的‘handle_ColorChanges’匹配委託>「系統.EventHandler」「

所以像

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1)); 

button1.Click += new EventHandler(KK.ChangeColor(button1)); 

錯誤說,需要一種方法,如果我用

「不超載的 'handle_ColorChanges' 匹配委託 'System.EventHandler'」

LAMBDA表達式幫助感謝您的支持答案

button1.Click += (sender,args) => KK.ChangeColor(s); 

但不允許取消分配和稍後將需要......

匿名委託有同樣的問題

button1.Click += delegate(object sender, EventArgs e) 
      { KK.ChangeColor(sender); }; 

問題的關鍵是,我的顏色方法或它們的委託不匹配按鈕委託簽名(對象,事件)。我不在乎按鈕參數,想用我自己的如何?

+0

的'新EventHandler'東西是可選的,因爲C#2.0中做到這一點。 – CodesInChaos

+0

相關問題:[C#爲什麼我要在訂閱事件時使用「new」關鍵字?](http://stackoverflow.com/questions/7751247/c-sharp-why-shall-i-use-new-keyword-當事件訂閱) – CodesInChaos

+1

這些問題主要因爲我詢問有關添加委託或EventHandler 其中MyArgT:EventArgs是自定義事件參數,並且不匹配按鈕的默認簽名。 –

回答

2

委託的使用是否正確?

是的,你在做什麼被分配一個anonymous delegate您的事件處理器。這是完全有效的,但是,這裏的問題是你不能取消分配事件處理程序,因爲你沒有引用它。你可以保持它的引用,這樣做的(如果需要)

var clickHandler = delegate { ... }; 
button1.Click += clickHandler; 
... 
button1.Click -= clickHandler 

如果您需要訪問事件處理程序的參數,你將需要添加那些到簽名例如

button1.Click += delegate (object sender, EventArgs args) { ... } 

new EventHandler(SomeHandlerMethod)結構是做事很長的路要走,它的同義+= SomeHandlerMethod。您的代碼目前不工作,因爲你正在試圖實際呼叫在構造函數中的處理程序時的構造函數需要一個參考的方法

+= new EventHandler<ColorEventArgs>(KK.ChangeColor); 

是否有更好的結構嗎?

是的,你可以使用甚至更少代碼

button1.Click += (s, args) => KK.ChangeColor(button1); 
2

這是不正確的:

button1.Click += new EventHandler<AutoRndColorEventArgs>(KK.ChangeColor(button1)); 

相反的KK.ChangeColor(button1),你只需要指定事件處理方法名像你一樣在這裏:

KK.ColorEventHandler += handle_ColorChanges; 

事件處理方法簽名應該匹配與EventHandler委託。如果您只想在事件處理程序中調用方法,則可以使用如下的lambda語句:

button1.Click += (s,e) => KK.ChangeColor(s); 

或者:

button1.Click += delegate(object s, EventArgs e) { KK.ChangeColor(s); }; 

通過這樣做,你正在創建一個匿名方法並將其連接到您的Click事件。

相關問題