C# 有关控件、自定义类事件中的委托链的获取、移除操作
直接来代码吧,这样干脆直接,也不耽误我午休了。一切尽在源码中。
public class ControlEventTool
{ /// <summary>
/// 移除控件的某类事件, 如Click事件
/// 2018.3.21
/// </summary>
public static void DemoRemoveControlEvents(System.Windows.Forms.Button btn, string eventName = "Click")
{
// 检索按钮的事件,这里单击事件的名字是EventClick,要注意的
Delegate[] invokeList = GetObjectEventList(btn, "Event" + eventName);
if (invokeList != null)
{
foreach (Delegate del in invokeList)
{
// 我已经测试,事件被全部取消了,没有问题。
typeof(System.Windows.Forms.Button).GetEvent(eventName).RemoveEventHandler(btn, del);
}
}
} /// <summary>
/// 获取控件指定事件的委托列表
/// </summary>
/// <param name="p_Control">对象</param>
/// <param name="p_EventName">事件名 EventClick、EventDoubleClick、EventMouseMove</param>
/// <returns>委托列</returns>
public static Delegate[] GetObjectEventList(Control p_object, string p_EventName)
{
PropertyInfo _PropertyInfo;
FieldInfo fieldInfo;
EventHandlerList evList;
Delegate d;
object _EventList; _PropertyInfo = p_object.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
if (_PropertyInfo == null) return null;
_EventList = _PropertyInfo.GetValue(p_object, null); if (_EventList == null || !(_EventList is EventHandlerList)) return null;
evList = (EventHandlerList)_EventList;
fieldInfo = (typeof(Control)).GetField(p_EventName, BindingFlags.Static | BindingFlags.NonPublic);
if (fieldInfo == null) return null; d = evList[fieldInfo.GetValue(p_object)];
if (d == null) return null; return d.GetInvocationList();
} public static void PrintControlEventDelegateList(System.Windows.Forms.Button btn, string eventName = "MouseMove")
{ PropertyInfo pi = btn.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
EventHandlerList ehl = (EventHandlerList)pi.GetValue(btn, null);//EventClick FieldInfo fieldInfo = (typeof(System.Windows.Forms.Control)).GetField("Event" + eventName, BindingFlags.Static | BindingFlags.NonPublic);
Delegate d = ehl[fieldInfo.GetValue(null)]; if (d == null)
{
Console.WriteLine("Typed Event \"{0}\" not exist in target control!", eventName);
return;
} foreach (Delegate del in d.GetInvocationList())
Console.WriteLine(del.Method.Name);
} /// <summary>
/// 对于指定类中自定义事件,移除其中的委托链的全部订阅方法,
/// 或者移除委托链中的指定方法名的订阅。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="c"></param>
/// <param name="event_name"></param>
/// <param name="methodname"></param>
public static void RemoveEvent<T>(T c, string event_name, string methodname = "")
{
Delegate[] invokeList = GetObjectEventList_V2(c, event_name);
if (invokeList == null) return; foreach (Delegate del in invokeList)
{
if (methodname!="" && del.Method.Name != methodname)
continue;
typeof(T).GetEvent(event_name).RemoveEventHandler(c, del);
//Console.WriteLine("Remove an event of " + event_name);
}
} public static Delegate[] GetObjectEventList_V2(object p_object, string p_EventName)
{
FieldInfo _fieldInfo;
Delegate _ObjDele;
object _FieldValue; _fieldInfo = p_object.GetType().GetField(p_EventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public);
if (_fieldInfo == null) return null;
_FieldValue = _fieldInfo.GetValue(p_object); if (_FieldValue == null || !(_FieldValue is Delegate)) return null;
_ObjDele = (Delegate)_FieldValue; return _ObjDele.GetInvocationList();
} #region Demo2 public class TEST
{
public event EventHandler AA; public void Foo()
{
if (AA!=null)
{
AA(this,new EventArgs()); //invoke the event
}
}
} public static void DemoUse2()
{ TEST obj_a = new TEST();
obj_a.AA += obj_a_AA;
obj_a.Foo(); RemoveEvent<TEST>(obj_a, "AA");
obj_a.Foo(); Console.WriteLine("Finished!"); } static void obj_a_AA(object sender, EventArgs e)
{
Console.WriteLine("Evnet rasied!");
} #endregion #region Demo public static void DemoUse()
{ System.Windows.Forms.Button btn = new System.Windows.Forms.Button();
btn.Click += new EventHandler(btn_Click);
btn.Click += new EventHandler(btn_Click2);
btn.Click += new EventHandler(btn_Click3);
btn.MouseMove += btn_MouseMove;
btn.MouseMove += btn_MouseMove2; // print before
Console.WriteLine("Before");
PrintControlEventDelegateList(btn);
PrintControlEventDelegateList(btn, "Click"); // del delegate
DemoRemoveControlEvents(btn, "Click"); // print after
Console.WriteLine("After");
PrintControlEventDelegateList(btn);
PrintControlEventDelegateList(btn, "Click"); } static void btn_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
throw new NotImplementedException();
} static void btn_MouseMove2(object sender, System.Windows.Forms.MouseEventArgs e)
{
throw new NotImplementedException();
} static void btn_Click(object sender, EventArgs e)
{
Console.WriteLine("Click1");
} static void btn_Click2(object sender, EventArgs e)
{
Console.WriteLine("Click2");
} static void btn_Click3(object sender, EventArgs e)
{
Console.WriteLine("Click3");
} #endregion }
C# 有关控件、自定义类事件中的委托链的获取、移除操作的更多相关文章
- 陈年佳酿之 - Winform ListView 控件 double click 事件中获取选中的row与column
背景 最近收到了一个关于以前项目的维护请求,那时的楼主还是刚刚工作的小青年~~~ 项目之前使用的是.net/winform.今天重新打开代码,看着之前在FrameWork2.0下面的代码, 满满的回忆 ...
- 在CTreeCtrl控件点击事件中获取点击的项
网上搜了一下,有两种方法: 1.使用GetSelectedItem() HTREEITEM hItem = m_treeCtrl.GetSelectedItem(); CString strText ...
- C#中combobox 控件属性、事件、方法
一 .combobox 属性.事件.方法公共属性 名称 说明 AccessibilityObject 获取分配给该控件的 AccessibleObject. AccessibleDefaultActi ...
- 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素
[源码下载] 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中 ...
- 背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件
[源码下载] 背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件 作者:webabcd 介绍 ...
- 背水一战 Windows 10 (68) - 控件(控件基类): UIElement - Pointer 相关事件, Tap 相关事件, Key 相关事件, Focus 相关事件
[源码下载] 背水一战 Windows 10 (68) - 控件(控件基类): UIElement - Pointer 相关事件, Tap 相关事件, Key 相关事件, Focus 相关事件 作者: ...
- asp.net中的ListBox控件添加双击事件
问题:在Aspx页里的ListBox A中添加双击事件,将选中项添加到另一个ListBox B中,双击ListBox B中的选中项,删除当前选中项 页面: <asp:ListBox ID=&qu ...
- 使用Devexpress中的CharControl控件,需要控制AxisY轴的显示范围,需要使用该控件的BoundDataChanged事件
一.控制ChartControl的Y轴范围 使用Devexpress中的CharControl控件,需要控制AxisY轴的显示范围,需要使用该控件的BoundDataChanged事件,具体代码如下: ...
- winform自定义控件中其他遮挡控件点击事件
自定义控件在其他窗口调用时,里面的lable阻挡了控件的点击事件 解决方法 自定义控件中lable的 点击事件 private void Lable1_Click(object sender, Eve ...
随机推荐
- [sklearn]性能度量之AUC值(from sklearn.metrics import roc_auc_curve)
原创博文,转载请注明出处! 1.AUC AUC(Area Under ROC Curve),即ROC曲线下面积. 2.AUC意义 若学习器A的ROC曲线被学习器B的ROC曲线包围,则学习器B的性能优于 ...
- 程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)
目录 第六章:数组 6-1 数组 6-2 数组计算 6.3 课后习题 第六章:数组 6-1 数组 题目:让用户输入一组整数以-1结束输入,算出这组数的平均值,并且输出大于平均值的数. 我们需要记录用户 ...
- CSS琐碎[1]
(1)letter-spacing 设置字符间局,用长度指定(百分比兼容性不好) 没有间距 间距6px API:http://gucong3000.github.io/css-book/propert ...
- Linux 中断处理
HardIRQ 和 softirq : http://www.it165.net/os/html/201211/3766.html 博文:http://blog.csdn.net/yin262/art ...
- IIS反向代理/Rewrite/https卸载配置
目标,使IIS具有类似与Nginx的功能,将指定域名的请求重定向到IIS内.IIS外.其他机器上的其他端口,并且实现https卸载功能 重点预告: 1.安装最新版urlrewrite(微软开发的)插件 ...
- BZOJ2933 [Poi1999]地图【区间DP】
Description 一个人口统计办公室要绘制一张地图.由于技术的原因只能使用少量的颜色.两个有相同或相近人口的区域在地图应用相同的颜色.例如一种颜色k,则A(k) 是相应的数,则有: 在用颜色k的 ...
- 关于MySQL 通用查询日志和慢查询日志分析
MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句. 2)慢查 ...
- 洛谷 4525 && 洛谷 4526 【模板】自适应辛普森法
题目:https://www.luogu.org/problemnew/show/P4525 https://www.luogu.org/problemnew/show/P4526 参考:https: ...
- 解决ueditor中没法动态配置imageurlprefix的方法
[建议使用右边文章中的方法,本篇文章没有真正的解决问题](新)解决php版本ueditor中动态配置图片URL前缀(imageurlprefix)的方法 修改背景,由于后台图片是上传到挂载的静态资源磁 ...
- Web API 路由访问设置
前段时间一直致力于MVC webapi 技术的研究,中途也遇到过好多阻碍,特别是api路由的设置和URL的访问形式,所以针对这个问题,特意做出了记录,以供日后有同样困惑的大虾们借鉴: 在Mvc WEB ...