none
WPF中,在窗体B中移除窗体A中的Button1的Click事件处理方法(委托) RRS feed

  • 问题

  • WPF程序,我创建两个窗体,WindowsA中有一个Button1,事件处理方法为Button1_Click。Button1为public,Button1_Click为private。

    在WindowsB中,我点击某个按钮会显示实例化一个WindowsA并Show出来,在Show之前,我想取消WindowsA中Button1的Click事件处理方法Button1_Click,重新添加一个WindowsB中的处理方法WindowsB_Click_WIndowsAButton方法。

    如何实现(WPF程序)。

    2014年9月17日 1:46

答案

  • 第一次实现方式:

            static void ClearWPFEvent(Control control, string eventname)
            {
                if (control == null) return;
                if (string.IsNullOrEmpty(eventname)) return;
                Type type = control.GetType();                          
                EventInfo eventInfo = type.GetEvent(eventname, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                if (eventInfo != null)
                {
                    FieldInfo fieldInfo = eventInfo.DeclaringType.GetField("ClickEvent", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                    if (fieldInfo != null)
                    {
                        fieldInfo.SetValue(control, null);
                        RoutedEvent event1 = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, eventInfo.EventHandlerType, control.GetType());
                        fieldInfo.SetValue(control, event1);
                    }
                }
            }

    这样实现的方式有一个问题就是,所有Button的点击事件都没有了。这个不是我想要的结果。经过今天一个小时的试验,找到了下面的正确实现方法:

                Type type = mainWindow.ClickButton.GetType();
                EventInfo eventInfo = type.GetEvent("Click");
                Type tdelegate = eventInfo.EventHandlerType;
                MethodInfo method = mainWindow.GetType()
                    .GetMethod("Button_Click_1", BindingFlags.NonPublic | BindingFlags.Instance);
                Delegate d = Delegate.CreateDelegate(tdelegate, mainWindow, method);
                eventInfo.RemoveEventHandler(mainWindow.ClickButton, d);

    注意倒数第二行,创建委托时,第二个参数target应该是窗体,不能是Button,因为这个方法本身属于窗体而不是属于Button。

     

    • 已标记为答案 王长春1 2014年9月18日 8:20
    2014年9月18日 8:20

全部回复

  • 第一次实现方式:

            static void ClearWPFEvent(Control control, string eventname)
            {
                if (control == null) return;
                if (string.IsNullOrEmpty(eventname)) return;
                Type type = control.GetType();                          
                EventInfo eventInfo = type.GetEvent(eventname, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                if (eventInfo != null)
                {
                    FieldInfo fieldInfo = eventInfo.DeclaringType.GetField("ClickEvent", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                    if (fieldInfo != null)
                    {
                        fieldInfo.SetValue(control, null);
                        RoutedEvent event1 = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, eventInfo.EventHandlerType, control.GetType());
                        fieldInfo.SetValue(control, event1);
                    }
                }
            }

    这样实现的方式有一个问题就是,所有Button的点击事件都没有了。这个不是我想要的结果。经过今天一个小时的试验,找到了下面的正确实现方法:

                Type type = mainWindow.ClickButton.GetType();
                EventInfo eventInfo = type.GetEvent("Click");
                Type tdelegate = eventInfo.EventHandlerType;
                MethodInfo method = mainWindow.GetType()
                    .GetMethod("Button_Click_1", BindingFlags.NonPublic | BindingFlags.Instance);
                Delegate d = Delegate.CreateDelegate(tdelegate, mainWindow, method);
                eventInfo.RemoveEventHandler(mainWindow.ClickButton, d);

    注意倒数第二行,创建委托时,第二个参数target应该是窗体,不能是Button,因为这个方法本身属于窗体而不是属于Button。

     

    • 已标记为答案 王长春1 2014年9月18日 8:20
    2014年9月18日 8:20
  • 这里为什么不支持上传附件。工程源码就不上传了。需要的可以联系我。邮箱。
    2014年9月18日 8:21