确定绑定到事件的事件处理程序列表 [英] Determine list of event handlers bound to event

查看:31
本文介绍了确定绑定到事件的事件处理程序列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个无法关闭的 WinForms 表单.在 OnFormClosing 中,e.Cancel 设置为 true.我猜我的应用程序中的某个对象已绑定到 Closing 或 FormClosing 事件,并且正在阻止关闭.为了找出答案,我想确定哪些代表绑定到这些事件之一.

I have a WinForms form that won't close. In OnFormClosing, e.Cancel is set to true. I am guessing that some object in my application has bound to the Closing or FormClosing event, and is blocking the close. To find out, I'd like to determine what delegates are bound to one of these events.

有没有办法确定绑定到事件的处理程序列表?理想情况下,我会通过 Visual Studio 调试器执行此操作,但可以在应用程序中编写代码以在必要时查找处理程序.了解到事件就像一个隐藏的私有字段,我已经通过调试器导航到表单的Windows.Forms.Form"祖先的非公共字段",但无济于事.

Is there a way to determine the list of handlers bound to an event? Ideally I would do this via the Visual Studio debugger, but can write code in the application to find the handlers if necessary. Understanding that an event is like a hidden private field, I've navigated through the Debugger to the "Non-Public Fields" for the "Windows.Forms.Form" ancestor of my form, but to no avail.

推荐答案

简而言之,您不打算这样做 - 而是出于调试目的...

In short, you're not meant to do this - but for debugging purposes...

一个事件经常由一个私有域支持——但没有控制;他们使用 EventHandlerList 方法.您必须访问表单的受保护 Events 成员,查找映射到(私有)EVENT_FORMCLOSING 对象的对象.

An event is often backed by a private field - but not with controls; they use the EventHandlerList approach. You would have to access the form's protected Events member, looking for the object mapped to the (private) EVENT_FORMCLOSING object.

一旦你有了 FormClosingEventHandlerGetInvocationList 就应该完成这项工作.

Once you have the FormClosingEventHandler, GetInvocationList should do the job.

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
class MyForm : Form
{
    public MyForm()
    { // assume we don't know this...
        Name = "My Form";
        FormClosing += Foo;
        FormClosing += Bar;
    }

    void Foo(object sender, FormClosingEventArgs e) { }
    void Bar(object sender, FormClosingEventArgs e) { }

    static void Main()
    {
        Form form = new MyForm();
        EventHandlerList events = (EventHandlerList)typeof(Component)
            .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(form, null);
        object key = typeof(Form)
            .GetField("EVENT_FORMCLOSING", BindingFlags.NonPublic | BindingFlags.Static)
            .GetValue(null);

        Delegate handlers = events[key];
        foreach (Delegate handler in handlers.GetInvocationList())
        {
            MethodInfo method = handler.Method;
            string name = handler.Target == null ? "" : handler.Target.ToString();
            if (handler.Target is Control) name = ((Control)handler.Target).Name;
            Console.WriteLine(name + "; " + method.DeclaringType.Name + "." + method.Name);
        }
    }
}

这篇关于确定绑定到事件的事件处理程序列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆