我已经看到了几个答案,但不知何故我无法让我的工作。我想动态使用各种控件(文本框、复选框、按钮等)的任何事件,最好将它们分配给一个事件处理程序。应在运行时分配处理程序。此外,我想在处理程序中知道哪个事件触发了处理程序。
我得到了这个部分工作。使用 lambda 表达式,我调用我的处理程序 (EventAssistant) 并传递一个包含事件名称的额外参数 (command)。它适用于使用 EventHandler 类型的事件。但是,它不适用于需要不同处理程序的事件,例如 MouseEventHandler 类型。它将无法在 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
}
作为替代方案,我尝试使用表达式树来解决问题,如下所示:为什么动态创建事件处理程序时出现参数异常? 显然,可以从 EventInfo 中检索 EventHandlerType 并在 lambda 表达式中使用。
但是,无论我做什么,我总是得到一个 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());
}
}
我在表达式树上做错了什么?
此外,第一段代码看起来更干净。是否有可能使用第一个代码示例得到我想要的?