将额外的参数传递给事件处理程序?

问题描述 投票:58回答:8

假设我要在分配事件处理程序时传递一些额外的数据。考虑以下代码:

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

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

我将如何将someData放入我的evHandler方法中?

c# events callback
8个回答
54
投票
private void setup(string someData)
{
     Object.assignHandler((sender) => evHandler(sender,someData));
}
public void evHandler(Object sender, string someData)
{
    // need someData here!!!
}

26
投票

我很难弄清楚上面@spender的示例,特别是在使用Object.assignHandler((sender) => evHandler(sender,someData));时,因为从字面上看,没有Object.assignHandler这样的东西。因此,我做了更多谷歌搜索并发现了this example。彼得·杜尼奥(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。 :)

/ snip

使用该示例,我能够使用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对象的非线程安全异常,我认为该异常不会更改示例的工作方式)。我现在正在弄清楚。


18
投票

捕获的变量:

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

3
投票

您可以尝试这样做:

string yourObject;

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

1
投票

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

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

0
投票

嗯,使someData成为成员变量的最简单方法id如下:

public class MyClass
{
    private string _eventData;

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

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

我不确定这是best的实现方式,但实际上取决于事件类型,对象等。>>


0
投票

您可以基于对象创建具有其他属性的自定义对象:


0
投票

这是我的单行解决方案,它将额外的参数传递给计时器处理程序。

© www.soinside.com 2019 - 2024. All rights reserved.