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