C# 将EventHandler传递给方法

C# 将EventHandler传递给方法,c#,C#,我正在尝试将eventHandler传递给方法。 在我的方法中,我将使用不同类型的EventHandler。例如KeyDownEventHandler、ClickEventHandler等 这能做到吗 @神秘性 下面是完整的测试代码。就像我说的,我正在尝试传递EventHandlers的名称。正如你在这里看到的那样。但是当我到达for-each时,它只是文本,而不是真正的事件处理程序。之后,在foreach循环中,您将看到它应该在何处删除或添加事件(订阅或取消订阅)。当我工作到一半的时候。取消订

我正在尝试将eventHandler传递给方法。 在我的方法中,我将使用不同类型的EventHandler。例如KeyDownEventHandler、ClickEventHandler等

这能做到吗

@神秘性

下面是完整的测试代码。就像我说的,我正在尝试传递EventHandlers的名称。正如你在这里看到的那样。但是当我到达for-each时,它只是文本,而不是真正的事件处理程序。之后,在foreach循环中,您将看到它应该在何处删除或添加事件(订阅或取消订阅)。当我工作到一半的时候。取消订阅的remove eventhandler不起作用。它应该工作的方式是,我有6个订阅的事件,它们都是相同的form1 event+=用于textbox1 to textchange to hit。当它点击并且我点击时,它进入DisableEvents方法,它抛出foreach,然后当它完成时,它再次返回textbox1_textbox1_textchange。6次。我希望DisableEvents删除另一个订阅的。根据最后一个变量,true或false将设置或删除它。如果有什么我可以帮助解决的地方,请告诉我。 @神秘性 以下是描述我的问题的最佳方式。form1设置订阅(+=)。然后在textBox1_textChanged事件中,我只添加了一行textBox1.textChanged-=null;就这样。当我运行代码6时,订阅被设置,当我点击文本框并键入任何一个字符时,文本框1_改变点击。我认为-=null应该清除所有订阅,而textbox1\u Changed在我订阅之前不会再次出现。我哪里做错了?我想把它放在一个方法中,这样我就可以传递参数了。但我想这是做不到的,也可以做到。我会继续读下去。谢谢

    public Form1()
    {
        InitializeComponent();

        //Setup the subscribed here         

        textBox1.TextChanged += textBox1_TextChanged;
        textBox1.TextChanged += textBox1_TextChanged;
        textBox1.TextChanged += textBox1_TextChanged;
        textBox1.TextChanged += textBox1_TextChanged;
        textBox1.TextChanged += textBox1_TextChanged;
        textBox1.TextChanged += textBox1_TextChanged;
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        DisableEvents(textBox1, "TextChanged", textBox1_TextChanged, false);
    }

    private static Delegate[] DisableEvents(object target, string eventName, EventHandler eventHandlerName, bool add)
    {
        FieldInfo fieldInfo = typeof(Control).GetField("Event" + eventName, BindingFlags.NonPublic | BindingFlags.Static);

        PropertyInfo propertyInfo = target.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

        EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(target, null) as EventHandlerList;

        object eventKey = fieldInfo.GetValue(target);

        var _eventHandler = eventHandlerList[eventKey] as Delegate;

        if (_eventHandler == null)
            return null;

        Delegate[] invocationList = _eventHandler.GetInvocationList();

        foreach (eventHandlerName item in invocationList)
        {
            if (add)
            {
                target.GetType().GetEvent(eventName).AddEventHandler(target, item);
            }
            else
            {
                target.GetType().GetEvent(eventName).RemoveEventHandler(target, item);
            }
        }
        return invocationList;
    }



//here is the example.
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;

namespace MyEventsExample
{
public partial class Form1 : DevExpress.XtraEditors.XtraForm
{
    public Form1()
    {
        InitializeComponent();
        //Subscribe 8 times
        for (int c = 0; c < 7; c++)
        {
            textBox1.KeyDown += textBox1_KeyDown;

            MessageBox.Show("Events added at Start # : " + c.ToString());
        }

        button1.Click += button1_Click;
    }

    int a;
    int b;
    int c;

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        //This should take the subscribed += and remove them -=.

        EventDescriptor edTypeDescriptor.GetEvents(textBox1).Find     ("KeyDown", true);

        if (ed != null)
        {
            for (int i = 0; i < ed.Attributes.Count; i++)
            {
                ed.RemoveEventHandler(textBox1, Delegate.CreateDelegate(typeof(KeyEventHandler), this, "textBox1_KeyDown"));
            }
        }

        //after the above is done this event should not work at all any more unless i subscribe to it again
        //But it keeps hitting the event the total of the subscried time in this case 8 times it enters in.                                                  
//when i make my method ill need a way to pass the typeof in this            case       its    the KeyEWvenHandler.

        a++;

        MessageBox.Show("Done " + a);
    }
    private void button1_Click(object sender, EventArgs e)
    {
        //Lets do it again
        //Subscribe 8 times
        for (int b = 0; b < 7; b++)
        {
            textBox1.KeyDown += textBox1_KeyDown;

            MessageBox.Show("Event Button Add  # : " + b.ToString());
        }
    }
}
public Form1()
{
初始化组件();
//在此处设置订阅的
textBox1.TextChanged+=textBox1\u TextChanged;
textBox1.TextChanged+=textBox1\u TextChanged;
textBox1.TextChanged+=textBox1\u TextChanged;
textBox1.TextChanged+=textBox1\u TextChanged;
textBox1.TextChanged+=textBox1\u TextChanged;
textBox1.TextChanged+=textBox1\u TextChanged;
}
私有void textBox1\u TextChanged(对象发送方,事件参数e)
{
禁用事件(textBox1,“TextChanged”,textBox1\u TextChanged,false);
}
私有静态委托[]DisableEvents(对象目标、字符串eventName、EventHandler eventHandlerName、bool add)
{
FieldInfo FieldInfo=typeof(Control).GetField(“事件”+eventName,BindingFlags.NonPublic | BindingFlags.Static);
PropertyInfo PropertyInfo=target.GetType().GetProperty(“事件”,BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
EventHandlerList EventHandlerList=(EventHandlerList)propertyInfo.GetValue(target,null)作为EventHandlerList;
对象eventKey=fieldInfo.GetValue(目标);
var\u eventHandler=eventHandlerList[eventKey]作为委托;
if(_eventHandler==null)
返回null;
委托[]调用列表=_eventHandler.GetInvocationList();
foreach(调用列表中的eventHandlerName项)
{
如果(添加)
{
target.GetType().GetEvent(eventName).AddEventHandler(目标,项);
}
其他的
{
target.GetType().GetEvent(eventName).RemoveEventHandler(目标,项);
}
}
返回调用列表;
}
//这是一个例子。
使用制度;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
名称空间MyEventSample
{
公共部分类表单1:DevExpress.XtraEditors.XtraForm
{
公共表格1()
{
初始化组件();
//订阅8次
对于(int c=0;c<7;c++)
{
textBox1.KeyDown+=textbox1u KeyDown;
MessageBox.Show(“在开始时添加的事件:”+c.ToString());
}
按钮1.点击+=按钮1\u点击;
}
INTA;
int b;
INTC;
私有void textBox1\u KeyDown(对象发送方,KeyEventArgs e)
{
//这将获取订阅的+=并删除它们-=。
EventDescriptor edTypeDescriptor.GetEvents(textBox1.Find)(“KeyDown”,true);
如果(ed!=null)
{
对于(int i=0;i
}
我需要将textBox1中的代码放入一个方法中,该方法将控件类型(如textbox)和事件操作(如textbox_KeyDown)传递给一个方法,但大多数事件处理程序(如textBox1_KeyDown事件)都是它的keydeventhandler。但最重要的是,我将方法传递给的对象清除了所有事件

事件处理程序和事件之间存在差异

事件处理程序只是一个委托。它可以毫无问题地传递

以这个代码为例:

Action foo = () => Console.WriteLine("1");

foo += () => Console.WriteLine("2");

foo();
调用时,它会写出
1
2

我可以将
Action foo
作为参数传递给任何方法。问题是代理是不可变的
Action bar = foo;

bar += () => Console.WriteLine("3");

foo();
bar();
TextBox textBox = new TextBox();

IObservable<EventPattern<TextBox, KeyEventArgs>> keyDowns =
    Observable
        .FromEventPattern<TextBox, KeyEventArgs>(
            textBox, "KeyDown");

IDisposable textBoxKeyDownsSubscription =
    keyDowns
        .Subscribe(ep =>
        {
            // Use `ep.Sender` & `ep.EventArgs` here
            // Both are strongly-typed
        });
TextBox textBox = new TextBox();

IObservable<EventPattern<TextBox, KeyEventArgs>> keyDowns =
    Observable
        .FromEventPattern<TextBox, KeyEventArgs>(
            textBox, "KeyDown");

bool enabled = true;

IObservable<Keys> onlyAOrBWhenEnabled =
    from kd in keyDowns
    where kd.EventArgs.KeyCode == Keys.A || kd.EventArgs.KeyCode == Keys.B
    where enabled == true
    select kd.EventArgs.KeyCode;

IDisposable onlyAOrBWhenEnabledSubscription =
    onlyAOrBWhenEnabled
        .Subscribe(keyCode =>
        {
            // Use `keyCode` here
        });