对某个控件的事件进行编程;如,需要将当前运行期的按钮替换掉,并且保留它的原始事件引用;方法如下:
测试代码
看不到图的请直接copy code
代码
private void button1_Click( object sender, EventArgs e) { MessageBox.Show( " click by " + ((Button)sender).Name); } public void button2_Click( object sender, EventArgs e) { // 调用button1 的click事件,并传递参数 CalleventRaiseEvent(button1, " Click ", button1, null); } private void button3_Click( object sender, EventArgs e) { // 构造个新的按钮 var btn3 = new Button { Name = " btnTest_createNew ", Text = " 新按钮 ", Parent = this, Left = button1.Left + button1.Width + 10, Top = button1.Top, Visible = true }; // btn3.Click += (s, a) => CalleventRaiseEvent(button1, "Click", button1, null); // 将旧按钮事件放到新按钮上去 ReplaceEvent(button1, btn3, " Click "); // 删除旧按钮 button1.Dispose(); button1 = null; } /// <summary> /// 替换事件到控件 /// 必须保证 EventHandler 类型一致,否则会失败 /// </summary> /// <param name="sourceControl"> 原控件 </param> /// <param name="destControl"> 目标控件 </param> /// <param name="eventName"> 事件明 </param> public void ReplaceEvent(Control sourceControl, Control destControl, string eventName) { if (sourceControl == null || destControl == null || string.IsNullOrEmpty(eventName)) throw new NullReferenceException(); Type type = sourceControl.GetType(); PropertyInfo propertyInfo = type.GetProperty( " Events ", BindingFlags.Instance | BindingFlags.NonPublic); var eventHandlerList = (EventHandlerList)propertyInfo.GetValue(sourceControl, null); FieldInfo fieldInfo = ( typeof(Control)).GetField( " Event " + eventName, BindingFlags.Static | BindingFlags.NonPublic); Delegate d = eventHandlerList[fieldInfo.GetValue( null)]; if (d != null) { foreach (Delegate di in d.GetInvocationList()) destControl.GetType().GetEvent(eventName).AddEventHandler(destControl, d); } else throw new InvalidCastException( " 无效的事件转换! "); } /// <summary> /// 调用事件方法 /// </summary> /// <param name="control"> 目标控件 </param> /// <param name="eventName"> 方法名 </param> /// <param name="args"> 方法参数 </param> public void CalleventRaiseEvent(Control control, string eventName, params object[] args) { if (control == null || string.IsNullOrEmpty(eventName)) throw new NullReferenceException(); Type type = control.GetType(); EventInfo eventInfo = type.GetEvent(eventName); MethodInfo methodInfo = eventInfo.GetRaiseMethod(); if (methodInfo != null) methodInfo.Invoke( this, args); else { PropertyInfo propertyInfo = type.GetProperty( " Events ", BindingFlags.Instance | BindingFlags.NonPublic); var eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null); FieldInfo fieldInfo = ( typeof(Control)).GetField( " Event " + eventName, BindingFlags.Static | BindingFlags.NonPublic); Delegate d = eventHandlerList[fieldInfo.GetValue( null)]; if (d != null) { foreach (Delegate di in d.GetInvocationList()) di.DynamicInvoke(args); } else throw new NullReferenceException( " 无效的事件激发! "); } }