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