使用反射取出实例挂勾的事件列表

工作中,常常需要在程序的运行中,查看一个实例(如控件,或其它实体类)所挂勾的事件,以及事件方法名等等。

编写以下代码,可以基本上实现这个目的。但有某些事件还是不能取出来,比如,以下代码中的TextBox的TextChanged事件。欢迎网友读过后,若能帮忙点评修正,不胜感激!

实现代码:

    private void btnAddHandler_Click(object sender, EventArgs e)
        {
            //为测试控件(TextBox,GridView)挂事件,便于后面测试
            this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
            this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged2);
            this.textBox1.Click += new EventHandler(textBox1_Click);

            this.gridView1.FocusedRowChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventHandler(gridView1_FocusedRowChanged);
            this.gridView1.FocusedRowChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventHandler(gridView1_FocusedRowChanged2);

            this.gridView1.CustomColumnDisplayText += new DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventHandler(gridView1_CustomColumnDisplayText);
        }

        private void btnAnalyseHandler_Click(object sender, EventArgs e)
        {
            //建立DataTable,存储事件与挂载信息
            DataTable dt = new DataTable();
            dt.Columns.Add("fCtrName", typeof(string));
            dt.Columns.Add("fEventName", typeof(string));
            dt.Columns.Add("fEventObj", typeof(string));

            GetHandlerInfo(gridView1, dt);
            GetHandlerInfo(textBox1, dt);
        }

        void GetHandlerInfo(object obj, DataTable dt)
        {
            //取出事件列表
            EventInfo[] arrEventInfo = obj.GetType().GetEvents();

            //定义取出事件列表的BindingFlags
            BindingFlags xEventBinds = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic;

            #region 定义取出事件的挂勾的BindingFlags
            int xFlags = 0;
            Array arrBinds = System.Enum.GetValues(typeof(BindingFlags));
            for (int i = 0; i < arrBinds.Length; i++)
            {
                xFlags += (int)arrBinds.GetValue(i);
            }

            BindingFlags xAllBinds = (BindingFlags)xFlags;
            #endregion

            PropertyInfo xPropInfo = obj.GetType().GetProperty("Events", xEventBinds);
            //取出已挂勾的事件列表
            EventHandlerList xHandlerList = xPropInfo.GetValue(obj, null) as EventHandlerList;

            FieldInfo xInfoTmp = null;
            Delegate dTmp = null;
            DataRow drNew = null;

            //取出控件名
            string sName = "";
            PropertyInfo xPropName = obj.GetType().GetProperty("Name");
            if (xPropName != null)
            {
                sName = xPropName.GetValue(obj, null).ToString();
            }

            //按事件列表循环
            foreach (EventInfo xInfo in arrEventInfo)
            {
                //反射取出事件
                xInfoTmp = GetEventFieldInfo(obj.GetType(), xInfo.Name, xAllBinds);
                if (xInfoTmp != null)
                {
                    //取出事件实体
                    dTmp = xHandlerList[xInfoTmp.GetValue(obj)] as Delegate;
                    if (dTmp != null)
                    {
                        //循环取出事件中挂载的一个或多个触发方法
                        foreach (Delegate dTmp2 in dTmp.GetInvocationList())
                        {
                            drNew = dt.NewRow();
                            drNew["fCtrName"] = sName;
                            drNew["fEventName"] = xInfo.Name;
                            drNew["fEventObj"] = dTmp2.Method.Name;
                            dt.Rows.Add(drNew);
                        }
                    }
                }
            }
        }

        //从类型,基类型中取出事件
        FieldInfo GetEventFieldInfo(Type tType, string sEventName, BindingFlags xBindFlags)
        {
            FieldInfo xInfo = tType.GetField("Event" + sEventName, xBindFlags);
            if (xInfo == null)
            {
                xInfo = tType.GetField(sEventName, xBindFlags);
            }
            if (xInfo != null || tType.BaseType == null)
                return xInfo;
            else
            {
                //事件可能在基类中,故使用递归返回
                return GetEventFieldInfo(tType.BaseType, sEventName, xBindFlags);
            }
        }




        void gridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
        {

        }

        void gridView1_FocusedRowChanged2(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {

        }

        void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {

        }

        void textBox1_Click(object sender, EventArgs e)
        {

        }

        void textBox1_TextChanged2(object sender, EventArgs e)
        {

        }

        void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值