Search code examples
c#eventsrouted-events

Event Handler not removing


I have a routed event handler for a media player to fire an event when the media player opens. When I have just one media element, i can remove the handler just fine. However, when I play two media elements at once with a single mouse click, it will not remove one of the events. The variable 'selZoneBOList' stores a different media element for each index in the list.

Here is where I add the event:

RoutedEventHandler mediaOpenedHandler;
List<RoutedEventHandler> delegateList = new List<RoutedEventHandler>();
private void playPlayerCrowdFile(int index) {
     mediaOpenedHandler = (sender, e) => 
     InterruptMediaElement_MediaOpened(sender, e, index);
     selZoneBOList[index].InterruptMediaElement.MediaOpened += mediaOpenedHandler;
     delegateList.Add(mediaOpenedHandler);
}

Here is the event method:

private void InterruptMediaElement_MediaOpened(object sender, RoutedEventArgs e, int index) {
     Console.WriteLine("count before " + delegateList.Count);
     selZoneBOList[index].InterruptMediaElement.MediaOpened -= mediaOpenedHandler;
     delegateList.Remove(mediaOpenedHandler);
     Console.WriteLine("count after " + delegateList.Count);
}

The output is the following:

count before 2,

count after 1,

count before 1,

count after 1

Why can I not remove the second event?


Solution

  • Because you are overwriting your mediaOpenedHandler field.

    Since your methods are indexed based, how about this:

    Dictionary<int, RoutedEventHandler> delegateList = new Dictionary<int, RoutedEventHandler>();
    private void playPlayerCrowdFile(int index)
    {
         var mediaOpenedHandler = (sender, e) => 
         InterruptMediaElement_MediaOpened(sender, e, index);
         selZoneBOList[index].InterruptMediaElement.MediaOpened += mediaOpenedHandler;
         delegateList.Add(index, mediaOpenedHandler);
    }
    
    private void InterruptMediaElement_MediaOpened(object sender, RoutedEventArgs e, int index)
    {
         Console.WriteLine("count before " + delegateList.Count);
         selZoneBOList[index].InterruptMediaElement.MediaOpened -= delegateList[index];
         delegateList.Remove(index);
         Console.WriteLine("count after " + delegateList.Count);
    }