因为要对一大批MenuItem做相同操作,但不知道他们的Click事件都添加了哪些EventHandler,能否在只给出MenuItem对象的情况下,移除Click事件的所有EventHandler?
private void Form1_Load(object sender, EventArgs e) { this.components = new System.ComponentModel.Container(); MainMenu mainMenu = new MainMenu(this.components); var menuFile = new MenuItem("File"); MenuItem menu = new MenuItem("Test"); menuFile.MenuItems.Add(menu); mainMenu.MenuItems.Add(menuFile); this.Menu = mainMenu; menu.Click += new EventHandler(menu_Click); } void menu_Click(object sender, EventArgs e) { MessageBox.Show("MenuClick"); }
能否在MenuItem的基础上实现功能?
Button btn = new Button(); btn.Click += btnStart_Click; btn.Click += btnStart_Click; EventInfo ei = btn.GetType().GetEvent("Click"); PropertyInfo propertyInfo = (typeof(Button)).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic); EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(btn, null); FieldInfo fieldInfo = (typeof(Control)).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic); Delegate d = eventHandlerList[fieldInfo.GetValue(null)]; if (d != null) { foreach (Delegate temp in d.GetInvocationList()) { btn.Click -= temp as EventHandler; } }
我已经试过了.是可以的,楼上的方法不行不通的.
Click事件是不能点GetInvocationList()方法的,
编译都通过不了.会提示
事件“System.Windows.Forms.Control.Click”只能出现在 += 或 -= 的左边
这个方法对Button或许有效,对MenuItem无效。
MenuItem根本就没有继承Control类
@沧海一杰: 你说的没错.我试过了.确实不行.
能不能绕过去呢.当需要修改事件绑定的时候,记录一个状态,在事件里利用状态再调用不同的代码是可以呢.?
你这个是WinForm的程序吗? 用这段代码试下吧,原理基本上还是和二楼相同的。
1 var dataField = menuItem.GetType().GetField("data", BindingFlags.Instance | BindingFlags.NonPublic); 2 var data = dataField.GetValue(menuItem); 3 4 var onClickField = data.GetType().GetField("onClick", BindingFlags.Instance | BindingFlags.NonPublic); 5 var onClickHanlder = onClickField.GetValue(data) as MulticastDelegate; 6 7 foreach (var currentHanlder in onClickHanlder.GetInvocationList()) 8 { 9 menuItem.Click -= currentHanlder as EventHandler; 10 }
onClickField.GetValue(data) 获取的结果为null, 仍然不行
用另一种方法解决了。解决办法:将原有菜单隐藏,在相同位置插入一个新菜单,样子完全仿制老菜单,为新菜单写click事件。
那还是绕过去了.?还是不能正确的解除绑定.?