WPF Custom Routed Events - How to UnSubscribe?

2019-06-19 00:00发布

问题:

How to DeRegister from one Custom Routed Event.

I have the following code (very standard for Custom Routed Events)

//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
    });
}

Now a class will subscribe to this event with this line:

//Receive the Movement events
EventManager.RegisterClassHandler( 
      typeof(Window)
    , Main.MovementEvent
    , new Main.MovementRoutedEventHandler(MovementHandler));

When I close the class instance, I should UnSubscribe from the event (otherwise, instance won't be garbage collected).

What should I call? I tried RegisterClassHandler(typeof(Window), Main.MovementEvent, **null**) but I get an exception...

Any help welcome. Thanks in advance.

JM

回答1:

You can use RemoveHandler method from System.Windows.Window class (generally from UIElement class).

The code could look something like this:

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


回答2:

I'm not sure if I completely understand what you're doing, but I'll throw in my two cents.

Your EventManager.RegisterClassHandler call should be placed in a static constructor for your class you wish to register. This will apply to all of your instances of the class and should not affect garbage collection.

If you wish to make register/unregister to the event on a per instance level, use the traditional

myEvent += myDelegate;
myEvent -= myDelegate;

Hope this helps.