【发布时间】:2019-10-28 12:29:09
【问题描述】:
我在 WPF 中有一个订阅 Click 事件的自定义控件 (MenuButton)。我现在想使用反射来取消订阅该事件。这是我的代码目前的样子:
private void RemoveClickEvent(MenuButton mbButton)
{
FieldInfo fiFieldInfo = mbButton.GetType().GetField("Click", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance |BindingFlags.Static | BindingFlags.GetField);
object objValue = fiFieldInfo.GetValue(mbButton);
PropertyInfo piProprtyInfo = mbButton.GetType().GetProperty("Events", BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static | BindingFlags.GetField | BindingFlags.GetProperty);
EventHandlerList ehEventHandlers = (EventHandlerList)piProprtyInfo.GetValue(mbButton, null);
ehEventHandlers.RemoveHandler(objValue, ehEventHandlers[objValue]);
}
我可以成功获取 FieldInfo 对象,但 PropertyInfo 对象显示为空。如何修复我的代码以使该方法正常工作?作为记录,我的目标是 .NET Framework 4。
编辑:
这是我订阅事件的方式。
private void PageStart()
{
//Subscribe to the necessary event when a page is first loaded
foreach (MenuButton mbItem in mbMenuButtonsList)
{
if (mbItem.HideExtraInfo == true)
{
mbButton.Click += (sender, e) => ShowOrHideControls(sender, e, true);
}
else
{
mbButton.Click += (sender, e) => ShowOrHideControls(sender, e, false);
}
}
}
private void PageEnd()
{
//When moving to the next page, unsubscribe from the events
foreach (MenuButton mbItem in mbMenuButtonsList)
{
RemoveClickEvent(mbItem);
}
}
编辑#2:
我忽略了一点,我在项目中使用的一些事件也需要传入 MenuButton,如下所示:
UIElementCollection ctrlControls = MainCanvas.Children;
mbButton.Click += (sender, e) => ChangeControls(sender, e, mbButton, ctrlControls, false);
如果我停止使用 Lambda 表达式,我该如何解决这个问题?
【问题讨论】:
-
WPF 中的事件是
RoutedEvent,我不确定您是否可以简单地使用反射来修改处理程序列表。 -
@TanveerBadar 如果我尝试的方法在 WPF 中是不可能的,你能建议另一种方法吗?
-
事件是如何订阅的?你能显示那个代码吗?一旦我们知道事件是如何连接起来的,取消订阅就会容易得多。
-
@TanveerBadar 问题已更新以显示此内容。
-
sender是 MenuButton 本身。
标签: c# wpf events reflection