首页新闻找找看学习计划

c# 如何remove MenuItem的Click事件的所有订阅(EventHandler)?

0
悬赏园豆:160 [已关闭问题] 关闭于 2012-12-18 14:14

因为要对一大批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的基础上实现功能?

沧海一杰的主页 沧海一杰 | 初学一级 | 园豆:48
提问于:2012-12-14 13:54
< >
分享
所有回答(4)
0

EventHandler.RemoveAll();就可以把所有的事件给移除。

想知道注册了那些事件可以

.GetInvocationList();

````` | 园豆:14268 (专家六级) | 2012-12-14 14:19
0
    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”只能出现在 += 或 -= 的左边

只会造轮子 | 园豆:2448 (老鸟四级) | 2012-12-14 14:23

这个方法对Button或许有效,对MenuItem无效。

支持(0) 反对(0) 沧海一杰 | 园豆:48 (初学一级) | 2012-12-14 14:51

MenuItem根本就没有继承Control类

支持(0) 反对(0) 沧海一杰 | 园豆:48 (初学一级) | 2012-12-14 14:54

@沧海一杰: 你说的没错.我试过了.确实不行.

能不能绕过去呢.当需要修改事件绑定的时候,记录一个状态,在事件里利用状态再调用不同的代码是可以呢.?

支持(0) 反对(0) 只会造轮子 | 园豆:2448 (老鸟四级) | 2012-12-14 15:51
0

你这个是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     }
天方 | 园豆:5264 (大侠五级) | 2012-12-16 16:13

onClickField.GetValue(data) 获取的结果为null, 仍然不行

支持(0) 反对(0) 沧海一杰 | 园豆:48 (初学一级) | 2012-12-18 14:11
0

用另一种方法解决了。解决办法:将原有菜单隐藏,在相同位置插入一个新菜单,样子完全仿制老菜单,为新菜单写click事件。

沧海一杰 | 园豆:48 (初学一级) | 2012-12-18 14:13

那还是绕过去了.?还是不能正确的解除绑定.?

支持(0) 反对(0) 只会造轮子 | 园豆:2448 (老鸟四级) | 2012-12-19 21:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册