gpt4 book ai didi

c# - 尝试取消订阅该 EventHandler 的变量时取消订阅原始事件

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:31 25 4
gpt4 key购买 nike

我正在尝试取消订阅我的事件的附加方法。我有这段代码:

public event EventHandler MenuItemSelectionChanged;

var eh = MenuItemSelectionChanged;
eh -= TheMethod;

运行上面的代码后结果是:

MenuItemSelectionChanged: Is Not Null

el: Is Null

但我想通过使用 eh(指向 EventHandler 的指针)从 MenuItemSelectionChanged 取消订阅 TheMethod。我如何使用 ehehMenuItemSelectionChanged

中删除 TheMethod

我需要这个结果:

MenuItemSelectionChanged: Is Null

el: Is 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) An enum value (to get event by it)

B) A method info (to unsubscribe its methodfrom the event)

注意:我的平台是 C#、WPF、.NET Framework 4.5

最佳答案

当您将 MenuItemSelectionChanged 移动到一个变量然后分配给该变量时,您并没有真正更改原始委托(delegate)的调用列表。 eh -= TheMethod;eh = eh - TheMethod; 相同(如果你在类中),但这会产生一个新的 MulticastDelegate 并且不修改原始代码。

所以要回答你的第一个代码:

public event EventHandler MenuItemSelectionChanged;

var eh = MenuItemSelectionChanged;
eh -= TheMethod;
MenuItemSelectionChanged = eh;

但是,您想要动态更改事件,因此您可以添加第二个方法来获取 ThisClassEventHandlerNamesEventHandler 并将其分配回去。或者您可以修改 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 现在“返回”对处理程序的引用,因此对它的所有更改都传递给 MenuItemSelectionChanged

关于c# - 尝试取消订阅该 EventHandler 的变量时取消订阅原始事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31597059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com