C#开发学习笔记:动态绑定控件事件

如何实现窗体中的按钮根据不同要求动态绑定不同的事件

1.首先可以新建一个类,在类中创建一个方法,该方法需要一个参数,为了方便可以直接传窗体对象,这样不管是想对窗体上的任何

控件进行动态绑定事件都可以直接获取到需要的控件

public static void SetStatusButtonEvent(Form form)

2.获取到相应的控件之后,将控件强转为原来的控件类型

BarLargeButtonItem lagerbutton = ItemLink.Item as BarLargeButtonItem;

3.通过指定的事件获取获取按钮相关事件的事件对象

 EventInfo eventInfo = lagerbutton.GetType().GetEvent("ItemClick",BindingFlags.Public | BindingFlags.Instance);
注:GetEvent方法中的第一个参数代表事件名,第二个参数的参数说明是一个位屏蔽,不知道具体代表什么,个人感觉就是通过Public和Instance

这两个修饰符来搜索相应类型的方法,这个参数具体意义可以通过个人理解,而GetEvent这个方法就是用来获取EventHandlerType(事件句柄类型)

EventInfo类型表示发现事件的属性并提供对事件元数据的访问权.


4,绑定事件

 MethodInfo doEventMethod = form.GetType().GetMethod(EventName,BindingFlags.NonPublic | BindingFlags.Instance);
定义一个MethodInfo类型的变量,GetMethod方法是使用指定绑定约束搜索自定方法,两个参数和上面GetEvent()方法一样的,这个方法是用来获取

需要绑定到控件上面的方法(根据你提供的方法名和要搜索的类型去搜索)

5,创建一个委托

 ItemClickEventHandler d = (ItemClickEventHandler)Delegate.CreateDelegate(eventInfo.EventHandlerType, form, doEventMethod);

这个变量类型的定义需要根据事件是事件触发类型来确定, CreateDelegate()创建委托,第一个参数就是要绑定的事件类型(每个事件都有指定的类型)

第二个参数,这里特别说明一下,这个参数表示要将委托绑定到的对象,可以为null,但是我不知道在什么样的情况下可以为null,为null时,后面的方法会被

当做static类型的方法,我在这里填的是form(窗体),一开始我这里t填写的是null,但是这样在后面测试时发现一个问题,当我触发事件之后,在事件内部

获取不到当前窗体的对象(this为null)而且获取不到任何窗体上的控件,后来发现我这里填写null时,创建个委托的target属性为null,我就用其他的事件

试了一下,其他事件的target都是指向到窗体的,所以我就把这里改为窗体对象,测试时一切正常


6.绑定委托到对象(这里和上面的CreateDelegate()的第二个参数的意思不一样)

eventInfo.AddEventHandler(lagerbutton, d);
AddEventHandler()将事件处理程序添加到事件源(触发事件的控件),第一个参数代表的就是事件源,第二个参数就是事件
这句话相当于lagerbutton.ItemClick+=new ItemClickEventHandler(事件名);

以上就是动态订阅事件的步骤,下面是我自己写的动态订阅的全部代码

using DevExpress.XtraBars;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RC
{
    /// <summary>
    /// 窗体底部按钮事件绑定专用类
    /// </summary>
    public class RCBindingEvent
    {

        #region 动态订阅事件
        /// <summary>
        /// 动态绑定F1-F12按钮事件(窗体底部功能按钮专用)
        /// </summary>
        /// <param name="form">当前窗体对象</param>
        public static void SetStatusButtonEvent(Form form)
        {
            foreach (Control control in form.Controls)
            {
                Type type = control.GetType();
                if (type.Name == "RCStatusButton")
                {
                    RC.RCStatusButton item = control as RC.RCStatusButton;
                    string itemName = item.Name;
                    foreach (BarItemLink ItemLink in item.bar3.ItemLinks)
                    {
                        BarLargeButtonItem lagerbutton = ItemLink.Item as BarLargeButtonItem;
                        if (lagerbutton != null)
                        {
                            int a = lagerbutton.Id;
                            try
                            {
                                //下面的代码主要解决如何动态订阅事件

                                EventInfo eventInfo = lagerbutton.GetType().GetEvent("ItemClick",
                                         BindingFlags.Public | BindingFlags.Instance);
                                BarButtonStyle aaa = lagerbutton.ButtonStyle;
                                string EventName = "";
                                if (lagerbutton.Name != "OKStatusButton" && 
                                    lagerbutton.Name != "CancelStatusButton"&&
                                    lagerbutton.Description=="Default")
                                    EventName = form.Name + "_RC_OK_" + lagerbutton.Name;
                                else
                                    EventName = form.Name + "_RC_PRE_" + lagerbutton.Name;
                                MethodInfo doEventMethod = form.GetType().GetMethod(EventName,
                                        BindingFlags.NonPublic | BindingFlags.Instance);
                                if (doEventMethod != null)
                                {
                                    //此处第二个参数一开始写的是null,导致虽然绑定了事件,但是事件触发之后获取不到事件所在的窗体的对象信息
                                    //是由于第二个参数表委托要绑定到的对象,这个对象具体怎么定义不知道,但是委托都有一个method属性和target属性
                                    //如果此处填null则创建的委托target属性为null,target为null就导致事件绑定到button上之后,在窗体中触发事件时
                                    //this(代表当前窗体)为null,表示窗体对象为null相当于窗体不存在,因此,个人理解CreateDelegate方法的第二个参数
                                    //所定义的委托要绑定到的对象中的对象代表的就是窗体
                                    ItemClickEventHandler d = (ItemClickEventHandler)Delegate.CreateDelegate(eventInfo.EventHandlerType, form, doEventMethod);
                                    eventInfo.AddEventHandler(lagerbutton, d);                                    
                                    //lagerbutton.PerformClick(ItemLink);//这句代码用于立即执行事件
                                }
                                if (lagerbutton.Name == "OKStatusButton" || lagerbutton.Name == "CancelStatusButton")
                                    lagerbutton.Enabled = false;
                            }
                            catch (Exception)
                            {

                                throw;
                            }
                        }
                    }
                }
            }
        }

        #endregion
       
    }
}


以上内容,纯属本人自己总结,如有雷同纯属巧合.

以上内容,纯属本人自己总结,如有不对请大神赐教.


  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值