C#中如何获得添加的事件? [英] c# How to get added events?

查看:204
本文介绍了C#中如何获得添加的事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我坐在我的电脑盈琢磨着怎么让所有添加的事件。我只是看了一些文章,包括 AC#睡前故事来更好地了解事件,我认为我主要的想法了。但我仍然无法弄清楚如何获得方法/如果事件被触发时执行代表名单。其实在我的情况下,它会是不够的,如果我知道,如果任何方法/委托分配给某个事件。
为例:我使用 Gma.UserActivityMonitor (键盘/鼠标挂钩)
现在我想知道,如果事件 HookManager.KeyUp 事件不是空。
如果是空的委托喊来添加。在我而言这一个\ /



  HookManager.KeyUp + =新KeyEventHandler(HookManager_KeyUp); 



修改



示例代码

 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Linq的;
使用System.Text;使用System.Windows.Forms的
;
使用的System.Reflection;
使用Gma.UserActivityMonitor;

命名空间EventTest
{
公共部分Form1类:表格
{
公共Form1中()
{
的InitializeComponent() ;
HookManager.KeyUp + =新KeyEventHandler(HookManager_KeyUp);
代表[] A = GetEventSubscribers(按钮1,点击);
label1.Text =一个[0] .Method.ToString();
}
无效HookManager_KeyUp(对象发件人,发送KeyEventArgs E)
{
/ *做某事* /
}
布尔NoEventAttached()
{
返回false;
}

公共静态代表[] GetEventSubscribers(对象的目标,字符串eventName的)
{
型T = target.GetType();
VAR eventInfo = t.GetEvent(eventName的,BindingFlags.Instance | BindingFlags.NonPublic可| BindingFlags.Public | BindingFlags.Static);


{
的FieldInfo [] = FIA t.GetFields(
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic可);

的foreach(字段信息网络FIA)
{
如果(fi.Name == eventName的)
{
代表D = fi.GetValue(目标)为代表;
如果(D!= NULL)
返回d.GetInvocationList();
}
,否则如果(fi.FieldType == typeof运算(EventHandlerList))
{
----> VAR OBJ = fi.GetValue(目标)作为EventHandlerList;
VAR eventHandlerFieldInfo = obj.GetType()getfield命令(头,BindingFlags.Instance | BindingFlags.NonPublic可)。

{
变种一个ListEntry = eventHandlerFieldInfo.GetValue(OBJ);
VAR处理器= listEntry.GetType()getfield命令(处理程序,BindingFlags.Instance | BindingFlags.NonPublic可)。
如果(处理!= NULL)
{
VAR SUBD = handler.GetValue(一个ListEntry)为代表;
如果(subD.GetType()= eventInfo.EventHandlerType!)
{
eventHandlerFieldInfo = listEntry.GetType()getfield命令(下一步,BindingFlags.Instance | BindingFlags.NonPublic可)。
OBJ =一个ListEntry为EventHandlerList; < -----------
继续;
}
如果(词表!= NULL)
{
返回subD.GetInvocationList();
}
}
}
,而(eventHandlerFieldInfo!= NULL);
}
}
T = t.BaseType;
},而(T!= NULL);
返回新的委托[] {};
}

私人无效的button1_Click(对象发件人,EventArgs五)
{

}

私人无效button1_MouseClick(对象发件人,MouseEventArgs E)
{

}


}
}


解决方案

请留意这个控制台应用程序,并专门排队叫号 GetInvocationList()。该方法返回附着代表的名单。每个代表有一个方法属性。每个方法属性有一个名称



委托通过您



 内部类节目
{
公共事件的EventHandler CheckInvocationList拥有;

私有静态无效的主要(字串[] args)
{
程序P =新计划();
p.CheckInvocationList + =新的EventHandler(p_CheckInvocationList);
p.Method1();

Console.WriteLine(的string.join(|,p.CheckInvocationList.GetInvocationList()选择(D => d.Method.Name).ToArray()));
}

静态无效p_CheckInvocationList(对象发件人,EventArgs五)
{
抛出新NotImplementedException();
}

公共无效方法1()
{
this.CheckInvocationList + =新的EventHandler(Program_CheckInvocationList);
}

无效Program_CheckInvocationList(对象发件人,EventArgs五)
{
抛出新NotImplementedException();
}
}



代表是不是归你



好吧,这变得有点凌乱,但它得到你想要的答案。即使内部实现使用 EventHandlerList (这是有些常见),我无法gaurantee那就绝对是每个场景中工作,因为可以有这么多不同的内部表示。



不过,希望这会为你工作。正如你所看到的例子我使用了的BackgroundWorker 类作为获取调用列表,因为我没有自己的特定事件我的例子类。

 使用系统; 
使用System.ComponentModel;
使用System.Linq的;
使用的System.Reflection;

内部类节目
{
私有静态无效的主要(字串[] args)
{
BackgroundWorker的工人=新的BackgroundWorker();
worker.DoWork + =新DoWorkEventHandler(worker_DoWork);
worker.DoWork + =新DoWorkEventHandler(worker_DoWork2);
worker.RunWorkerCompleted + =新RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.ProgressChanged + =新ProgressChangedEventHandler(worker_ProgressChanged);

Console.WriteLine(的string.join(|,GetEventSubscribers(工人的DoWork)选择(D => d.Method.Name).ToArray()));
}

静态无效worker_ProgressChanged(对象发件人,ProgressChangedEventArgs E)
{
抛出新NotImplementedException();
}

静态无效worker_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs E)
{
抛出新NotImplementedException();
}

静态无效worker_DoWork2(对象发件人,DoWorkEventArgs E)
{
抛出新NotImplementedException();
}

静态无效worker_DoWork(对象发件人,DoWorkEventArgs E)
{
抛出新System.NotImplementedException();
}

公共静态代表[] GetEventSubscribers(对象的目标,字符串eventName的)
{
型T = target.GetType();
VAR eventInfo = t.GetEvent(eventName的,BindingFlags.Instance | BindingFlags.NonPublic可| BindingFlags.Public | BindingFlags.Static);


{
的FieldInfo [] = FIA t.GetFields(
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic可);

的foreach(字段信息网络FIA)
{
如果(fi.Name == eventName的)
{
代表D = fi.GetValue(目标)为代表;
如果(D!= NULL)
返回d.GetInvocationList();
}
,否则如果(fi.FieldType == typeof运算(EventHandlerList))
{
动态的obj = fi.GetValue(目标)作为EventHandlerList;
VAR eventHandlerFieldInfo = obj.GetType()getfield命令(头,BindingFlags.Instance | BindingFlags.NonPublic可)。

{
变种一个ListEntry = eventHandlerFieldInfo.GetValue(OBJ);
VAR处理器= listEntry.GetType()getfield命令(处理程序,BindingFlags.Instance | BindingFlags.NonPublic可)。
如果(处理!= NULL)
{
VAR SUBD = handler.GetValue(一个ListEntry)为代表;
如果(subD.GetType()= eventInfo.EventHandlerType!)
{
eventHandlerFieldInfo = listEntry.GetType()getfield命令(下一步,BindingFlags.Instance | BindingFlags.NonPublic可)。
OBJ =一个ListEntry;
继续;
}
如果(词表!= NULL)
{
返回subD.GetInvocationList();
}
}
}
,而(eventHandlerFieldInfo!= NULL);
}
}

T = t.BaseType;
},而(T!= NULL);

返回新的委托[] {};
}
}



最后,虽然我做了一些相当大的修改到代码,我得给信贷鲍勃·鲍威尔以让我就这样开始了。


I am sitting infront of my pc wondering how to get all added events. I just read some articles including A C# Bedtime Story to better understand events and I think that I got the main idea now. But still I couldn't figure out how to get the List of methods/delegates that are executed if an event is fired. Actually in my case it'd be enough if I knew if any method/delegate is assigned to a certain event. for example: I am using Gma.UserActivityMonitor (for keyboard/mouse-hooking) Now I want to know if the event HookManager.KeyUp event is not null. If it is null a delegate shout be added. In my case this one \/

HookManager.KeyUp += new KeyEventHandler(HookManager_KeyUp);

Edit

example code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Gma.UserActivityMonitor;

namespace EventTest 
{ 
    public partial class Form1 : Form 
    { 
        public Form1() 
        { 
            InitializeComponent();             
            HookManager.KeyUp += new KeyEventHandler(HookManager_KeyUp);
            Delegate[] a = GetEventSubscribers(button1, "Click");
            label1.Text = a[0].Method.ToString();
        } 
        void HookManager_KeyUp(object sender, KeyEventArgs e) 
        {         
            /* Do something*/     
        } 
        bool NoEventAttached() 
        { 
            return false; 
        }

        public static Delegate[] GetEventSubscribers(object target, string eventName) 
        { 
            Type t = target.GetType(); 
            var eventInfo = t.GetEvent(eventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); 

            do 
            { 
                FieldInfo[] fia = t.GetFields(
                    BindingFlags.Static | 
                    BindingFlags.Instance | 
                    BindingFlags.NonPublic); 

                foreach (FieldInfo fi in fia) 
                { 
                    if (fi.Name == eventName) 
                    { 
                        Delegate d = fi.GetValue(target) as Delegate;                         
                        if (d != null)                         
                            return d.GetInvocationList(); 
                    } 
                    else if (fi.FieldType == typeof(EventHandlerList)) 
                    { 
                        ----> var obj = fi.GetValue(target) as EventHandlerList; 
                        var eventHandlerFieldInfo = obj.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic); 
                        do 
                        { 
                            var listEntry = eventHandlerFieldInfo.GetValue(obj); 
                            var handler = listEntry.GetType().GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic); 
                            if (handler != null) 
                            { 
                                var subD = handler.GetValue(listEntry) as Delegate; 
                                if (subD.GetType() != eventInfo.EventHandlerType) 
                                { 
                                    eventHandlerFieldInfo = listEntry.GetType().GetField("next", BindingFlags.Instance | BindingFlags.NonPublic); 
                                    obj = listEntry as EventHandlerList; <-----------
                                    continue; 
                                } 
                                if (subD != null) 
                                { 
                                    return subD.GetInvocationList(); 
                                } 
                            } 
                        } 
                        while (eventHandlerFieldInfo != null);                 
                    } 
                } 
                t = t.BaseType; 
            } while (t != null);          
            return new Delegate[] { }; 
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void button1_MouseClick(object sender, MouseEventArgs e)
        {

        }


    } 
}

解决方案

Take note to this console application, and specifically the line calling GetInvocationList(). That method returns the list of delegates attached. Each Delegate has a Method property. Each Method property has a Name.

Delegate is Owned by You

internal class Program
{
    public event EventHandler CheckInvocationList;

    private static void Main(string[] args)
    {
        Program p = new Program();
        p.CheckInvocationList += new EventHandler(p_CheckInvocationList);
        p.Method1();

        Console.WriteLine(string.Join(" | ", p.CheckInvocationList.GetInvocationList().Select(d => d.Method.Name).ToArray()));
    }

    static void p_CheckInvocationList(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    public void Method1()
    {
        this.CheckInvocationList += new EventHandler(Program_CheckInvocationList);
    }

    void Program_CheckInvocationList(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

Delegate is NOT Owned by You

Ok, this gets a little messy, but it gets you the answer you want. Even if the internal implementation uses an EventHandlerList (which is somewhat common), but I cannot gaurantee it would work in absolutely every scenario because there can be so many different internal representations.

However, hopefully this will work for you. As you can see in the example I'm using the BackgroundWorker class as my example class for getting the invocation list for a specific event I do not own.

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

internal class Program
{
    private static void Main(string[] args)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.DoWork += new DoWorkEventHandler(worker_DoWork2);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);

        Console.WriteLine(string.Join(" | ", GetEventSubscribers(worker, "DoWork").Select(d => d.Method.Name).ToArray()));
    }

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        throw new NotImplementedException();
    }

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        throw new NotImplementedException();
    }

    static void worker_DoWork2(object sender, DoWorkEventArgs e)
    {
        throw new NotImplementedException();
    }

    static void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        throw new System.NotImplementedException();
    }

    public static Delegate[] GetEventSubscribers(object target, string eventName)
    {
        Type t = target.GetType();
        var eventInfo = t.GetEvent(eventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

        do
        {
            FieldInfo[] fia = t.GetFields(
                 BindingFlags.Static |
                 BindingFlags.Instance |
                 BindingFlags.NonPublic);

            foreach (FieldInfo fi in fia)
            {
                if (fi.Name == eventName)
                {
                    Delegate d = fi.GetValue(target) as Delegate;
                    if (d != null)
                        return d.GetInvocationList();
                }
                else if (fi.FieldType == typeof(EventHandlerList))
                {
                    dynamic obj = fi.GetValue(target) as EventHandlerList;
                    var eventHandlerFieldInfo = obj.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
                    do
                    {
                        var listEntry = eventHandlerFieldInfo.GetValue(obj);
                        var handler = listEntry.GetType().GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
                        if (handler != null)
                        {
                            var subD = handler.GetValue(listEntry) as Delegate;
                            if (subD.GetType() != eventInfo.EventHandlerType)
                            {
                                eventHandlerFieldInfo = listEntry.GetType().GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
                                obj = listEntry;
                                continue;
                            }
                            if (subD != null)
                            {
                                return subD.GetInvocationList();
                            }
                        }
                    }
                    while (eventHandlerFieldInfo != null);
                }
            }

            t = t.BaseType;
        } while (t != null);

        return new Delegate[] { };
    }
}

Finally, though I made some pretty big modifications to the code, I have to give credit to Bob Powell for getting me started on this.

这篇关于C#中如何获得添加的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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