WPF(C#)真正能移除所有事件的註冊事件列表的代碼!

經過多方試驗,終於找到下面的方法,可以移動諸如Window上的Closed事件註冊的處理方法。這個是行之有效的,記錄下來,以備後用。上代碼:

        void ClearEvent(Control control, string eventname)
        {
            if (control == null) return;
            if (string.IsNullOrEmpty(eventname)) return;

            BindingFlags mPropertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic;
            BindingFlags mFieldFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Static;
            Type controlType = control.GetType();
            PropertyInfo propertyInfo = controlType.GetProperty("Events", mPropertyFlags);
            if (propertyInfo == null)
            {
                Type baseType = control.GetType(); ;
                while ((baseType = baseType.BaseType) != typeof(object) && propertyInfo == null)
                {
                    propertyInfo = baseType.GetProperty("Events", mPropertyFlags);
                }
            }
            EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(control, null);
            FieldInfo fieldInfo = control.GetType().GetField("Event_" + eventname, mFieldFlags);
            if (fieldInfo == null)
            {
                Type baseType = control.GetType();
                while ((baseType = baseType.BaseType) != typeof(object) && fieldInfo == null)
                {
                    fieldInfo = baseType.GetField("Event_" + eventname, mFieldFlags);
                }
            }
            Delegate d = eventHandlerList[fieldInfo.GetValue(control)];

            if (d == null) return;
            EventInfo eventInfo = controlType.GetEvent(eventname);

            foreach (Delegate dx in d.GetInvocationList())
                eventInfo.RemoveEventHandler(control, dx);
        } 

調用如下:

var myWin = new MyWindow();
ClearEvent(myWin , "Closed");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章