WPF自定义路由事件-如何取消订阅?

6
如何取消注册一个自定义路由事件。
我有以下代码(非常标准的自定义路由事件):
//Dispatch the Video Detection Movements
public delegate void MovementRoutedEventHandler( object sender
                                                , MovementRoutedEventArgs e);
public class MovementRoutedEventArgs : RoutedEventArgs
{
    private readonly DahuaDevice _device;
    private readonly byte[] _canals;
    private readonly DateTime _when;

    public MovementRoutedEventArgs(DahuaDevice device, byte[] canals, DateTime when)
    {
        _device = device;
        _canals = canals;
        _when = when;
    }
    public DahuaDevice Device
    {
        get { return _device; }
    }
    public Byte[] Canals
    {
        get { return _canals; }
    }
    public DateTime When
    {
        get { return _when; }
    }
}
public static RoutedEvent MovementEvent = EventManager.RegisterRoutedEvent(
        "Movement"
    , RoutingStrategy.Tunnel
    , typeof(MovementRoutedEventHandler)
    , typeof(Window)
);

public event RoutedEventHandler Movement
{
    add { AddHandler(MovementEvent, value); }
    remove { RemoveHandler(MovementEvent, value); }
}
public void RaiseMovementEvent(DahuaDevice device, byte[] canals, DateTime when)
{
    RaiseEvent(new MovementRoutedEventArgs(device, canals, when)
    {
        RoutedEvent = MovementEvent
    });
}

现在一个类将使用以下代码订阅此事件:
//Receive the Movement events
EventManager.RegisterClassHandler( 
      typeof(Window)
    , Main.MovementEvent
    , new Main.MovementRoutedEventHandler(MovementHandler));

当我关闭类实例时,我应该UnSubscribe事件(否则,实例将无法被垃圾收集)。
我该叫什么?我尝试了RegisterClassHandler(typeof(Window), Main.MovementEvent, **null**)但是我得到了一个异常...
欢迎任何帮助。提前感谢。
JM
2个回答

10

你可以使用System.Windows.Window类(通常来自UIElement类)的RemoveHandler方法。

代码可能会像这样:

Main.RemoveHandler( Main.MovementEvent
                  , new Main.MovementRoutedEventHandler(MovementHandler));

非常感谢您的快速回答。 - Jean-Marie
很高兴我能帮到你。 - Rafal Spacjer

6

我不确定我完全理解你在做什么,但是我想提供我的意见。

你的EventManager.RegisterClassHandler调用应该放在你想要注册的类的静态构造函数中。这将适用于你类的所有实例,不应影响垃圾回收。

如果你希望在每个实例级别上注册/注销事件,请使用传统方法。

myEvent += myDelegate;
myEvent -= myDelegate;

希望这能帮到您。

谢谢您的回答,但是当它们是“自定义路由事件”时,您可以直接使用+和-吗?我不确定。 我将把RegisterClassHandler放在静态构造函数中,以避免内存泄漏。 - Jean-Marie
是的,您可以使用“+”和“-”来处理自定义路由事件。这些事件在实例级别上使用,但是由于您的解决方案似乎希望类的所有实例都订阅该事件,因此EventManager.RegisterClassHandler是正确的方法。但是,还要注意注册到事件的方法应为静态方法,否则您将遇到您所担心的内存泄漏问题。请参见此链接:http://www.japf.fr/2009/08/wpf-memory-leak-with-eventmanager-registerclasshandler/ - philt5252

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接