在WPF中,移除一个事件中已经注册的处理方法,看似简单,实际还是很痛苦的一件事情。因为C#的灵活性,定义事件的方法也是多种多样。我自己定义了一个事件: public event EventHandler TestEvent; 当我想注销这个事件上注册的所有方法的时候,我可以按如下的方法进行 Delegate[] dels = TestEvent.

在WPF中,移除一个事件中已经注册的处理方法,看似简单,实际还是很痛苦的一件事情。因为C#的灵活性,定义事件的方法也是多种多样。
我自己定义了一个事件:

public event EventHandler TestEvent;

当我想注销这个事件上注册的所有方法的时候,我可以按如下的方法进行

 Delegate[] dels = TestEvent.GetInvocationList();
            foreach (var d in dels)
                TestEvent-= d as EventHandler;

但是,当我想注销一个Window上的Closed上注册的事件时,发现在Closed上根本没有GetInvocationList方法。这是怎么回事呢。通过反编译查看微软的代码,它的定义是这样的:

public event EventHandler Closed
    add{}
    remove{}

坑爹啊。度娘了半天,终于找到下面的方法参考完成。

/// <summary>
/// 清除一个对象的某个事件所挂钩的delegate
/// </summary>
/// <param name="ctrl">控件对象</param>
/// <param name="eventName">事件名称,默认的</param>
public static void ClearEvents(this object ctrl, string eventName = "_EventAll")
    if (ctrl == null) return;
    BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Static;
    EventInfo[] events = ctrl.GetType().GetEvents(bindingFlags);
    if (events == null || events.Length < 1) return;
    for (int i = 0; i < events.Length; i++)
            EventInfo ei = events[i];
            //只删除指定的方法,默认是_EventAll,前面加_是为了和系统的区分,防以后雷同
            if (eventName != "_EventAll" && ei.Name != eventName) continue;
            /********************************************************
             * class的每个event都对应了一个同名(变了,前面加了Event前缀)的private的delegate类
             * 型成员变量(这点可以用Reflector证实)。因为private成
             * 员变量无法在基类中进行修改,所以为了能够拿到base 
             * class中声明的事件,要从EventInfo的DeclaringType来获取
             * event对应的成员变量的FieldInfo并进行修改
             ********************************************************/
            FieldInfo fi = ei.DeclaringType.GetField("Event_" + ei.Name, bindingFlags);
            if (fi != null)
                // 将event对应的字段设置成null即可清除所有挂钩在该event上的delegate
                fi.SetValue(ctrl, null);
        catch { }

原来的代码中 ei.DeclaringType.GetField("Event_" + ei.Name, bindingFlags);的Event后面没有下划线,即写成了“Event”,执行时发现fi是空。参考上面的代码“_EventAll”,加一个下划线尝试。成功!
记录,以备后查。

如何使用原生的 JavaScript 代码,触发 SAP UI5 按钮控件的点击事件处理函数
如何使用原生的 JavaScript 代码,触发 SAP UI5 按钮控件的点击事件处理函数
1:什么是路由事件     WPF中的事件为路由事件,所谓路由事件,MSDN定义如下:     功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。 Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象
原文:Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象 原创文章,如需转载,请注明出处。 最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一下结论,欢迎交流指正。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/powertoolsteam/article/details/6109036 本以为Label也有TextChanged 事件,但在使用的时候却没找到,网友说Label的Content属性改变肯定是使用赋值操作,赋值的时候就可以对其进行相应的操作所以不需TextChanged
原文:WPF当属性值改变时利用PropertyChanged事件来加载动画     在我们的程序中,有时我们需要当绑定到UI界面上的属性值发生变化从而引起数据更新的时候能够加载一些动画,从而使数据更新的效果更佳绚丽,在我们的程序中尽量将动画作为一种资源放在xaml中,而不是在后台中通过写代码的这种方式来加载动画,在我们的这篇博客中我们尽量使用简洁的语言来阐述这一方法。
原文:WPF 路由事件 最近想封装一个关于手势的控件,但是由其他的控件覆盖之后发现不能触发,据说是有一些事件在定义的时候就处理过e.Handle了。 定义的时候就处理了,就是为了控件能够正常的工作,别如Button.MouseDown什么的。
原文:WPF 自定义路由事件 WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件。 1.WPF内置路由事件   WPF中的大多数事件都是路由事件,WPF有3中路由策略: 具体不多讲,单需要注意的是WPF路由事件是沿着VIsualTree传递的。