WEB开发网
开发学院软件开发C语言 C#中动态订阅控件中任意事件的方法 阅读

C#中动态订阅控件中任意事件的方法

 2010-09-30 22:42:48 来源:WEB开发网   
核心提示: 注意:如果是标准的事件委托,一般情况下都是第一个参数为object类型,C#中动态订阅控件中任意事件的方法(3),第二个参数为EventArgs绑定类型,无返回值的签名格式,还是在textBox2鼠标按钮被按下,都会直接触发DoTrigger函数,换句话说,一般情况下

注意:如果是标准的事件委托,一般情况下都是第一个参数为object类型,第二个参数为EventArgs绑定类型,无返回值的签名格式。换句话说,一般情况下,上面的这段代码返回的数组包含两个对象:object和一个继承于EventArgs(或者是EventArgs本身)的类型。在这里,我们取数组里的第二个成员。

好了,现在通过反射,获得DoTrigger方法的MethodInfo,并通过MethodInfo.MakeGenericMethod方法,将上一步获得的EventArgs类型绑定到DoTrigger方法上,并使用Delegate.CreateDelegate生成Event Handler:

01 private Delegate GetEventHandler(Control control, EventInfo eventInfo)
02 {
03     try
04     {
05         if (eventInfo == null)
06             throw new Exception(string.Format("Unable to find an event named '{0}' on the control '{1}'.",
07                 eventInfo.Name, control));
08         Type[] delegateParameters = this.GetDelegateParameterTypes(eventInfo.EventHandlerType);
09         if (delegateParameters == null ||
10             delegateParameters.Length != 2)
11             throw new InvalidOperationException(string.Format("Event '{0}' is not valid.", eventInfo.Name));
12         Type eventArgsType = delegateParameters[1];
13  
14         MethodInfo doEventMethod = this.GetType().GetMethod("DoTrigger",
15             BindingFlags.NonPublic | BindingFlags.Instance);
16  
17         if (doEventMethod == null)
18             throw new Exception("DoTrigger method doesn't exist.");
19         if (!doEventMethod.IsGenericMethod)
20             throw new Exception("DoTrigger method is not a generic method.");
21         MethodInfo concreteDoEventMethod = doEventMethod.MakeGenericMethod(eventArgsType);
22         Delegate d = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, concreteDoEventMethod);
23         return d;
24     }
25     catch
26     {
27         throw;
28     }
29 }

通过向上面的方法传入一个任意控件和该控件中任意事件的Method Info,即可获得处理该事件的Event Handler,也就是由DoTrigger泛型方法来处理该指定的事件:

01 public void RegisterTrigger(Control control, string eventName)
02 {
03     try
04     {
05         EventInfo eventInfo = control.GetType().GetEvent(eventName,
06             BindingFlags.Public | BindingFlags.Instance);
07  
08         Delegate d = this.GetEventHandler(control, eventInfo);
09         eventInfo.AddEventHandler(control, d);
10     }
11     catch
12     {
13         throw;
14     }
15 }

最后,在使用的时候,代码就简单啦:

1 private void Form_Load (object sender, System.EventArgs e)
2 {
3     this.RegisterTrigger (btn, "Click");
4     this.RegisterTrigger (textBox1, "TextChanged");
5     this.RegisterTrigger (textBox2, "MouseDown");
6 }

现在,不管是btn被单击,还是textBox1里的文字被更改,还是在textBox2鼠标按钮被按下,都会直接触发DoTrigger函数,进而使得“下一步”按钮变得可用(Enabled为true)。

上一页  1 2 3 

Tags:动态 订阅 控件

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接