C#传递额外的参数到事件处理程序?

比方说,我想在分配事件处理程序时传递一些额外的数据。 考虑下面的代码:

private void setup(string someData) { Object.assignHandler(evHandler); } public void evHandler(Object sender) { // need someData here!!! } 

我将如何去获取一些数据到我的evHandler方法?

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

捕获的variables:

 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); }); 

我很难找出@ spender上面的例子,特别是: Object.assignHandler((sender) => evHandler(sender,someData)); 因为在字面意义上没有Object.assignHandler这样的东西。 所以我做了一些Googlesearch,并find了这个例子 。 Peter Duniho的回答是在我脑中点击的(这不是我的工作):

SNIP

通常的做法是使用匿名方法来处理具有修改签名的事件处理程序。 例如:

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

当然,你不必在172中传递,甚至可以使第三个参数成为int。 🙂

/剪断

使用这个例子,我能够使用lambda表示法将两个自定义ComboBoxItem对象传递给Timer.Elapsed事件:

 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); } 

这不是上面例子中的任何新代码,但它确实演示了如何解释它们。 希望像我这样的人发现它的指导性和有用性,所以他们不花费时间来试图像我一样理解这个概念。

这个代码在我的项目中工作(除了ComboBoxItem对象的非线程安全exception,我不相信这个例子是如何工作的)。 我正在搞清楚。

你可以尝试这样做:

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

那么,最简​​单的方法ID使得someData成员variables如下所示:

 public class MyClass { private string _eventData; private void setup(string someData) { _eventData = someData; Object.assignHandler(evHandler); } public void evHandler() { // do something with _eventData here } } 

我不确定这是做到这一点的最好方法,但是这取决于事件types,对象等。

你可以创build一个基于Object的附加属性的自定义对象:

 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; } 

如果在初始化之后数据不应该再被改变,你也可以添加一个自定义的构造函数。

这是我的单行解决scheme,将额外的parameter passing给定时器处理程序。

 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)); } 

我的问题是类似的被标记为重复,所以我想在这里添加一个答案,因为它不会让我在我的问题。

 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); } }