Reputation: 17415
I'm trying to unsubscribe attached method to my event. I have this code:
public event EventHandler MenuItemSelectionChanged;
var eh = MenuItemSelectionChanged;
eh -= TheMethod;
After run the above code result is:
MenuItemSelectionChanged: Is Not Null
el: Is Null
But I want to unsubscribe TheMethod
from MenuItemSelectionChanged
, by using eh
(a pointer to the EventHandler). How can I use eh
to remove TheMethod
from eh
and MenuItemSelectionChanged
I need this result:
MenuItemSelectionChanged: Is Null
el: Is Null
My main scenario is:
Inside TargetClass.cs
:
public event EventHandler MenuItemSelectionChanged;
public void UnsubscribeFromEvent(ThisClassEventHandlerNames eventHandlerName, Dictionary<FrameworkElement, MethodInfo> eventHandlerInfos)
{
var eh = GetEventHandler(eventHandlerName);
if (eh == null) return;
foreach (var eventHandlerInfo in eventHandlerInfos)
{
var info = eventHandlerInfo;
if (eh == null)
break;
var invocationList = eh.GetInvocationList().Where(x =>
Equals(x.Target, info.Key) &&
x.Method == info.Value);
foreach (var myDeligate in invocationList)
{
if (eh == null)
break;
// I HAVE A PROBLEM HERE>>
eh -= (EventHandler) myDeligate;
// RESULT: eh is null BUT MenuItemSelectionChanged is not null
}
}
}
public enum ThisClassEventHandlerNames
{
MenuItemSelectionChanged
}
private EventHandler GetEventHandler(ThisClassEventHandlerNames eventHandlerName)
{
EventHandler result = null;
switch (eventHandlerName)
{
case ThisClassEventHandlerNames.MenuItemSelectionChanged:
{
result = MenuItemSelectionChanged;
break;
}
default:
{
result = null;
break;
}
}
return result;
}
I call the above code in my wpf user control with some codes like this:
Inside MyUserControl.cs
:
TargetClassObject.UnsubscribeFromEvent(
TargetClass.ThisClassEventHandlerNames.MenuItemSelectionChanged,
new Dictionary<FrameworkElement, MethodInfo>
{
{
this,
Infrastructure.Utility.GetMethodInfo<MyUserControl>(x => x.MenuControl_MenuItemSelectionChanged(null, null))
}
});
Really I want to unsubscribe a method from an event by call a method inside that class (targetClass
) by this parameters:
A) An enum value (to get event by it)
B) A method info (to unsubscribe its method from the event)
Note: My platform is C#, WPF, .NET Framework 4.5
Upvotes: 2
Views: 94
Reputation: 13187
When you move MenuItemSelectionChanged
to a variable and then assigning to that variable, you aren't really changing the original delegate's invocation list. eh -= TheMethod;
is just the same as eh = eh - TheMethod;
(if you are inside the class), but this produces a new MulticastDelegate
and doesn't modify the original one.
So to answer your first code:
public event EventHandler MenuItemSelectionChanged;
var eh = MenuItemSelectionChanged;
eh -= TheMethod;
MenuItemSelectionChanged = eh;
However, you want to change the event dynamically, so either you can add a second method that gets ThisClassEventHandlerNames
and EventHandler
and assigns it back. Or you can modify the GetEventHandler
method to return a reference to the handler:
private delegate void HandlerModifier(ref EventHandler handler);
private bool ModifyEventHandler(ThisClassEventHandlerNames eventHandlerName, HandlerModifier mod)
{
switch (eventHandlerName)
{
case ThisClassEventHandlerNames.MenuItemSelectionChanged:
{
mod(ref MenuItemSelectionChanged);
return true;
}
default:
{
return false;
}
}
}
public void UnsubscribeFromEvent(ThisClassEventHandlerNames eventHandlerName, Dictionary<FrameworkElement, MethodInfo> eventHandlerInfos)
{
ModifyEventHandler(
eventHandlerName,
delegate(ref EventHandler eh)
{
if (eh == null) return;
foreach (var eventHandlerInfo in eventHandlerInfos)
{
var info = eventHandlerInfo;
if (eh == null)
break;
var invocationList = eh.GetInvocationList().Where(x =>
Equals(x.Target, info.Key) &&
x.Method == info.Value);
foreach (var myDeligate in invocationList)
{
if (eh == null)
break;
// I HAVE A PROBLEM HERE>>
eh -= (EventHandler) myDeligate;
// RESULT: eh is null BUT MenuItemSelectionChanged is not null
}
}
}
);
}
ModifyEventHandler
now "returns" a reference to the handler, so all changes to it are passed to MenuItemSelectionChanged
.
Upvotes: 1