WEB开发网
开发学院软件开发C语言 动态调用对象事件 阅读

动态调用对象事件

 2010-09-30 22:39:56 来源:WEB开发网   
核心提示:对某个控件的事件进行编程;如,需要将当前运行期的按钮替换掉,动态调用对象事件,并且保留它的原始事件引用;方法如下:查看原图(大图)查看原图(大图)测试代码查看原图(大图)看不到图的请直接copy codeprivatevoidbutton1_Click(objectsender,EventArgse){MessageB

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

动态调用对象事件

查看原图(大图) 

动态调用对象事件

查看原图(大图)

测试代码

动态调用对象事件

查看原图(大图)

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

Tags:动态 调用 对象

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