工作中,常常需要在程序的运行中,查看一个实例(如控件,或其它实体类)所挂勾的事件,以及事件方法名等等。
编写以下代码,可以基本上实现这个目的。但有某些事件还是不能取出来,比如,以下代码中的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) { }