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

时间:2010-11-18 14:33:13

标签: c# events callback

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

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

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

我如何将一些数据放入我的evHandler方法?

8 个答案:

答案 0 :(得分:51)

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

答案 1 :(得分:20)

我很难弄清楚@ spender上面的例子,特别是:Object.assignHandler((sender) => evHandler(sender,someData));,因为字面意义上没有Object.assignHandler这样的东西。所以我做了一点谷歌搜索,发现this example。 Peter Duniho的答案就是点击了我的脑袋(这不是我的工作):

  

剪断

     

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

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对象的非线程安全异常,我不认为这会改变示例的工作方式)。我现在正在考虑这个问题。

答案 2 :(得分: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 :(得分:3)

您可以尝试这样做:

string yourObject;

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

答案 4 :(得分: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);
        }
    }

答案 5 :(得分: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
    }
}

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

答案 6 :(得分: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;
}

如果在初始化后不再更改数据,您还可以添加自定义构造函数,例如。

答案 7 :(得分: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));
}