【问题标题】:AddHandler only if no handlers for this event?仅当此事件没有处理程序时才添加处理程序?
【发布时间】:2010-01-25 07:08:14
【问题描述】:

我只想在未设置的情况下设置事件处理程序:

If GetHandlers(MyWindow.Closed, AddressOf MyWindow_Closed).Length = 0 Then
    AddHandler MyWindow.Closed, AddressOf MyWindow_Closed
EndIf

【问题讨论】:

    标签: vb.net delegates event-handling


    【解决方案1】:

    您无法真正查询事件委托的当前值,除非在定义事件的代码中。你在这里的意图是什么?通常你不应该(不必要地)太关心其他订阅者吗?有一些方法可以破解封装以找到当前值,但推荐使用它们(这不是一个好主意)。

    如果您关心的是您是否已经在使用 that 处理程序处理该事件(即您不想重复订阅,那么您可以随时选择:修复代码,使其不会t 这样做,或者 b: 作弊(C# 示例):

    // remove handler **if subscribed**, then re-subscribe
    myWindow.Closed -= MyWindow_Closed;
    myWindow.Closed += MyWindow_Closed;
    

    要获得调用列表是......脆弱但可行。在简单的情况下,您可以只使用反射来获取字段并获取值。但是对于表单等,它使用稀疏技术(以最小化没有订阅者的事件空间)。对于FormClosed,这是通过EVENT_FORMCLOSED 键入的。

    举个例子可能更有意义(C#,抱歉):

        Form form = new Form();
        form.FormClosed += delegate { Console.WriteLine("a");}; // just something, anything
        form.FormClosed += delegate { Console.WriteLine("b");}; // just something, anything
        object key = typeof(Form).GetField("EVENT_FORMCLOSED",
            BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
        EventHandlerList events = (EventHandlerList )
            typeof(Component).GetProperty("Events",
            BindingFlags.NonPublic | BindingFlags.Instance).GetValue(form, null);
        FormClosedEventHandler handler = (FormClosedEventHandler)events[key];
        foreach (FormClosedEventHandler subhandler in handler.GetInvocationList())
        {
            subhandler(form, null); // access the two events separately
        }
    

    ObservableCollection<T> 的情况下,委托直接在一个字段上,因此需要较少的间接:

    ObservableCollection<SomeType> list = ...
    NotifyCollectionChangedEventHandler handler = (NotifyCollectionChangedEventHandler)
        list.GetType()
        .GetField("CollectionChanged", BindingFlags.Instance | BindingFlags.NonPublic)
        .GetValue(list);
    

    【讨论】:

    • 我确实需要从事件中触发 GetInvocationList,有什么解决方法吗?
    • 就我而言,我需要获取 INotifyCollectionChanged.CollectionChanged 事件的调用列表 :( 我正在努力解决这个问题
    • @Shimmy - 这是 WPF 窗口吗?要不然是啥? exact(具体)类型在谈论反射时很重要。那么在您的情况下实现INotifyCollectionChanged 的是什么?
    • 其实可能位置不对,请看一下,stackoverflow.com/questions/2178703/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    相关资源
    最近更新 更多