动态事件认购事项及处理1 [英] Dynamic Event Subscription and 1 handler

查看:166
本文介绍了动态事件认购事项及处理1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经见过几个答案,但不知何故,我不能让我的工作。我想动态使用任何各种控制(文本框,复选框,按钮等)和,事件的优选,其中分配给一个事件处理程序。该处理器将会在运行时进行分配。此外,我想在这种情况触发处理程序的处理程序就知道了。

I have seen several answers already but somehow I can't get mine to work. I want to dynamically use any of the events of various controls (textbox, checkbox, button, etc) and, preferably, assign them to one event handler. The handler should be assigned at runtime. Furthermore, I want to know in the handler which event triggered the handler.

我得到了这部分工作。使用包含事件的名称Lambda表达式我打电话给我的处理程序(EventAssistant),并通过一个额外的参数(命令)。它适用于使用EventHandler类型的事件。然而,它不会为该期望一个不同的处理程序,如类型MouseEventHandler事件工作。它将无法在的addEventHandler订阅。

I got this to work partially. Using a lambda expression I call my handler (EventAssistant) and pass an extra parameter (command) which contains the name of the event. It works for events that use type EventHandler. However, it won't work for events that expect a different handler such as type MouseEventHandler. It will fail to subscribe at AddEventHandler.

private void RegisterEventHandlers(Control ctl)
{
  foreach (Command command in CommandList)
  {
    EventInfo eventInfo = ctl.GetType().GetEvent(command.Name);
    EventHandler handler = (sender, args) =>
    {
      EventAssistant(sender, args, command);
    };
    eventInfo.AddEventHandler(ctl, handler);
  }
}

public void EventAssistant(object sender, EventArgs e, Command c)
{
  //do lots of other fun stuff
}

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

作为替代我试图解决表达式树的问题,如下所示:的为什么动态创建的事件处理程序时,我得到一个参数异常?
显然,EventHandlerType可以从EventInfo检索在lambda表达式中使用。

As an alternative I tried to solve the problem with an Expression Tree as shown here: Why am I getting an Argument exception when creating event handler dynamically? Apparently, the EventHandlerType can be retrieved from the EventInfo and used in a lambda expression.

不过,无论我做什么,我总是得到一个InvalidOperationExceptionLAMBDA参数不在范围内。

But, whatever I do I always get an InvalidOperationException "Lambda Parameter not in scope".

private void RegisterEventHandlers(Control ctl)
{
  foreach (Command command in CommandList)
  {
    EventInfo eventInfo = ctl.GetType().GetEvent(command.Name);

    var sender = Expression.Parameter(typeof(object), "sender");
    var e = Expression.Parameter(typeof(EventArgs), "e");
    var c = Expression.Parameter(typeof(Command), "command");
    Expression[] arg = new Expression[] { sender, e, c };
    MethodInfo mi = this.GetType().GetMethod("EventAssistant");
    var body = Expression.Call(Expression.Constant(this), mi, arg);
    var lambda = Expression.Lambda(eventInfo.EventHandlerType, body, sender, e);

    eventInfo.AddEventHandler(ctl, lambda.Compile());
  }
}



我在做什么错误的表达式树?

What am I doing wrong with the Expression Tree?

此外,代码的第一件看起来很多更干净。是否有可能得到我想要使用的第一个代码示例是什么?

Also, the first piece of code looks a lot more clean. Is it possible to get what I want using the first code sample?

推荐答案

在你的第二次尝试,变量<$ C $ ç> C 不应该是一个 ParameterExpression ,但常量表达式的值集到目前命令来代替。在当前的代码,你正在创建一个处理程序,它本质上是这样的:

In your second attempt, the variable c shouldn't be a ParameterExpression, but a ConstantExpression with the value set to the current command instead. With the current code, you are creating a handler, which essentially looks like this:

(_sender, _e) => this.EventAssistant(_sender, _e, _c)
// The expression expects "_c" to be a parameter of the lambda, which is why
// you're getting that exception



However, if you change

var c = Expression.Parameter(typeof(Command), "command");



to

var c = Expression.Constant(command);



生成的代码看起来(和工作,当然)预期:

the generated code will look (and work, of course) as expected:

(_sender, _e) => this.EventAssistant(_sender, _e, command)

这篇关于动态事件认购事项及处理1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆