动态调用对象事件

对某个控件的事件进行编程;如,需要将当前运行期的按钮替换掉,并且保留它的原始事件引用;方法如下:

 

 测试代码

 看不到图的请直接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("无效的事件激发!");
            }
        }

 

 

posted @ 2010-01-25 12:38  suifei  阅读(2069)  评论(7编辑  收藏  举报