2010-11-18 173 views
50

假設我想在分配事件處理函數時傳遞一些額外的數據。考慮下面的代碼:C#將額外的參數傳遞給事件處理程序?

private void setup(string someData) 
{ 
    Object.assignHandler(evHandler); 
} 

public void evHandler(Object sender) 
{ 
    // need someData here!!! 
} 

我該如何去獲取someData到我的evHandler方法?

+0

我在這個問題上多標準解決方案,第一個答案http://stackoverflow.com/questions/14058412/passing-parameter-to-an-event-handler/14058441#14058441 – 2013-11-25 14:09:34

回答

49
private void setup(string someData) 
{ 
    Object.assignHandler((sender) => evHandler(sender,someData)); 
} 
public void evHandler(Object sender, string someData) 
{ 
    // need someData here!!! 
} 
+1

這是一個很好的解決方案,但是如果EventHandler已經有了TArgs。比如+ = new EventHandler (evHandler)? – Roast 2011-12-23 13:58:26

+0

嗨@Lily,這是不完全清楚你在問什麼。發佈一個問題(而不是評論)可能更好一些,並提供一些更詳細的信息和一些代碼來說明你正在嘗試做什麼。 – spender 2011-12-24 02:34:09

+1

謝謝,這解決了我遇到的一個問題,但我是C#的新手,所以你介意解釋一下這個語言構造是什麼,或者給我一個關鍵字給谷歌的解釋? – 2012-04-11 16:44:46

0

好,最簡單的方法ID,使someData一個成員變量,像這樣:

public class MyClass 
{ 
    private string _eventData; 

    private void setup(string someData) 
    { 
     _eventData = someData; 
     Object.assignHandler(evHandler); 
    } 

    public void evHandler() 
    { 
     // do something with _eventData here 
    } 
} 

我不知道那是最好方式做到這一點,但它確實取決於事件類型,對象等

+1

在想這個方法,但是可能會使用不同的someData調用多次setup。該數據應該對每個處理程序都是唯一的。 – 2010-11-18 14:39:38

+0

在這種情況下,spender或Marc的解決方案好得多 – CodingGorilla 2010-11-18 14:42:12

17

捕獲變量:

private void setup(string someData) 
{ 
    Object.assignHandler((sender,args) => { 
     evHandler(sender, someData); 
    }); 
} 

public void evHandler(Object sender, string someData) 
{ 
    // use someData here 
} 

或(C#2.0替代):

Object.assignHandler((EventHandler)delegate(object sender,EventArgs args) { 
     evHandler(sender, someData); 
    }); 
+2

被捕獲變量===閉包? – Matt 2010-11-18 14:39:31

+2

@Matt - 是的,捕獲的變量是詞法關閉。 – 2010-11-18 14:40:29

+0

澄清,是第一個對C#.NET 2.0無效的解決方案嗎? – 2010-11-18 14:43:36

2

你可以試試這樣做:

string yourObject; 

theClassWithTheEvent.myEvent += (sender, model) => 
{ 
yourObject = "somthing"; 
} 
0

基於對象,您可以創建具有附加屬性的自定義對象:

class CustomObject : Object 
{ 
    public string SomeData; 
} 

private void setup(string someData) 
{ 
    CustomObject customObject = new CustomObject { SomeData = someData }; 
    CustomObject.assignHandler(evHandler); 
} 

public void evHandler(Object sender) 
{ 
    string someData = ((CustomObject)sender).SomeData; 
} 

如果數據不能再修改例如,在初始化之後,您還可以添加自定義構造函數。

14

我很難搞清@ spender上面的例子,特別是:Object.assignHandler((sender) => evHandler(sender,someData));,因爲在字面意義上沒有Object.assignHandler這樣的東西。所以我多做了一點Google搜索,發現this example。彼得Duniho答案是,在我的腦海點擊一個(這不是我的工作):

剪斷

通常的方法是使用匿名方法與具有修改後的事件處理程序 簽名。例如:

void Onbutton_click(object sender, EventArgs e, int i) { ... } 

button.Click += delegate(object sender, EventArgs e) 
{ Onbutton_click(sender, e, 172); }; 

當然,你不必在172通過,甚至使第三個參數 一個int。 :)

/剪斷

使用的例子,我能在兩個自定義ComboBoxItem對象傳遞給Timer.Elapsed事件使用lambda符號:

simulatorTimer.Elapsed += 
(sender, e) => onTimedEvent(sender, e, 
(ComboBoxItem) cbPressureSetting.SelectedItem, 
(ComboBoxItem) cbTemperatureSetting.SelectedItem); 

,然後到它的處理程序:

static void onTimedEvent(object sender, EventArgs e, ComboBoxItem pressure, ComboBoxItem temperature) 
    { 
     Console.WriteLine("Requested pressure: {0} PSIA\nRequested temperature: {1}° C", pressure, temperature); 
    } 

這不是上述示例中的任何新代碼,但它確實證明了h解釋他們。希望像我這樣的人發現它很有用,所以他們不會像我一樣花費數小時來理解概念。

這段代碼在我的項目中工作(除了一個非線程安全的例外,我不相信這個例子會改變這個例子的工作方式)。我正在弄清楚這一點。

0

這是我的單線解決方案,它將額外的參數傳遞給定時器處理程序。

private void OnFailed(uint errorCode, string message) 
{ 
    ThreadPoolTimer.CreateTimer((timer) => { 
    UI.ErrorMessage = string.Format("Error: 0x{0:X} {1}", errorCode, message); 
    }, System.TimeSpan.FromMilliseconds(100)); 
} 
0

我的問題是類似的被標記爲重複所以我想在這裏添加一個答案,因爲它不會讓我對我的問題。

class Program 
    { 
     delegate void ComponentEventHandler(params dynamic[] args); 

     event ComponentEventHandler onTest; 

     static void Main(string[] args) 
     { 
      Program prg = new Program(); 

      // can be bound to event and called that way 
      prg.onTest += prg.Test; 
      prg.onTest.Invoke("What", 5, 12.0); 

      Console.ReadKey(); 
     } 

     public void Test(params dynamic[] values) 
     { 
      // assign our params to variables 
      string name = values[0]; 
      int age = values[1]; 
      double value = values[2]; 

      Console.WriteLine(name); 
      Console.WriteLine(age); 
      Console.WriteLine(value); 
     } 
    } 
相關問題