C# 【代码】鼠标消息和向下传播消息

C#

消息不能向下传递,上层控件处理了就不能往下传了,这对于整个窗体都要处理鼠标、个别控件有特殊处理这样的模式就有些麻烦

窗体里面每个控件都要设置事件代码,如果有遗漏编译不会出问题,很难发现

所以要用代码来给所有控件增加事件代码,从而等价实现了向下传播鼠标消息

入口是Control,对于Form可以直接用this,如果不需要整个窗体范围就用一个容器替代,针对的是MouseDown消息

FormEntry_MouseDown是Form的事件MouseDown的处理程序,通过窗体设计器添加的
myInit_AddEvent(this)可以将这个事件处理程序绑定到所有的子控件
 1         void myInit_AddEvent(Control control)
 2         {
 3             foreach (Control v in control.Controls)
 4             {
 5                 //判断是否已经设置了MouseDown,已经设置了则不再设置
 6                 PropertyInfo pi = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
 7                 EventHandlerList ehl = (EventHandlerList)pi.GetValue(v, null);
 8                 FieldInfo fieldInfo = (typeof(Control)).GetField("EventMouseDown", BindingFlags.Static | BindingFlags.NonPublic);
 9                 Delegate d = ehl[fieldInfo.GetValue(null)];
10 
11                 if (null == d)
12                 {
13                     //MessageBox.Show(v.ToString() + " null");
14                 }
15                 else
16                 {
17                     foreach (Delegate del in d.GetInvocationList())
18                     {//这个循环没什么用,只是演示了如何判断事件处理程序的名字
19                         //MessageBox.Show(v.ToString() + " " + del.Method.Name);
20                         if (del.Method.Name == "FormEntry_MouseDown")//这是事件处理程序的名字,可以单独写,也可以直接使用已经存在的事件处理程序
21                         {
22                             continue;
23                         }
24                     }
25                     if (d.GetInvocationList().Length > 0) continue;//这里判断的是如果设置过任何一个事件处理程序就不设置了。严格地讲,别的代码可能处于别的需要设置了事件处理程序,应该判断具体的名字
26                 }
27                 v.MouseDown += new MouseEventHandler(FormEntry_MouseDown);//设置事件处理程序
28                 myInit_AddEvent(v);//递归设置子控件
29             }
30         }
原文地址:https://www.cnblogs.com/shadowpigg/p/14010012.html