我试图取消订阅我的活动的附加方法。我有这段代码:
public event EventHandler MenuItemSelectionChanged;
var eh = MenuItemSelectionChanged;
eh -= TheMethod;
运行后上面的代码结果是:
MenuItemSelectionChanged:不为空
el:Null
但我希望使用TheMethod
(指向EventHandler的指针)取消订阅MenuItemSelectionChanged
eh
。如何使用eh
从TheMethod
和eh
移除MenuItemSelectionChanged
我需要这个结果:
MenuItemSelectionChanged:Null
el:Null
我的主要情景是:
内部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;
}
我在我的wpf用户控件中使用以下代码调用上面的代码:
内部MyUserControl.cs
:
TargetClassObject.UnsubscribeFromEvent(
TargetClass.ThisClassEventHandlerNames.MenuItemSelectionChanged,
new Dictionary<FrameworkElement, MethodInfo>
{
{
this,
Infrastructure.Utility.GetMethodInfo<MyUserControl>(x => x.MenuControl_MenuItemSelectionChanged(null, null))
}
});
我真的希望通过以下参数调用该类(targetClass
)中的方法来取消订阅事件中的方法:
A)枚举值(通过它获取事件)
B)方法信息(取消订阅其方法 来自活动)
注意:我的平台是C#,WPF,.NET Framework 4.5
答案 0 :(得分:1)
当您将MenuItemSelectionChanged
移动到变量然后分配给该变量时,您并没有真正更改原始委托的调用列表。 eh -= TheMethod;
与eh = eh - TheMethod;
相同(如果您在课堂内),但这会产生新的MulticastDelegate
,并且不会修改原始版本。
所以回答你的第一个代码:
public event EventHandler MenuItemSelectionChanged;
var eh = MenuItemSelectionChanged;
eh -= TheMethod;
MenuItemSelectionChanged = eh;
但是,您希望动态更改事件,因此您可以添加第二个获取ThisClassEventHandlerNames
和EventHandler
的方法并将其分配回来。或者您可以修改GetEventHandler
方法以将引用返回给处理程序:
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
现在&#34;返回&#34;对处理程序的引用,因此对它的所有更改都将传递给MenuItemSelectionChanged
。