首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

如何判断一个事件是否已经绑定了事件处理函数

2013-10-12 
怎么判断一个事件是否已经绑定了事件处理函数?比如我在winform里面,针对不同的情况,我要对KeyUp事件绑定不

怎么判断一个事件是否已经绑定了事件处理函数?
比如我在winform里面,针对不同的情况,我要对KeyUp事件绑定不同的处理函数。
但是绑定前,我需要判断一下KeyUp是否已经绑定了事件处理函数,该怎么判断呢?
[解决办法]
你可以 写一个KeyUp方法,把你所以要调用不同的KeyUp的控件,窗体的KeyUp 事件 绑定到你自己写的KeyUp上,
在这个方法里,做判断,其中 sender 里是你的控件属性, e是你键盘操作
这样你想怎么组合都可以,也可以都拆开写,随你,给你写个例子,你看看 这样能解决你的问题不



private void KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == 37 
[解决办法]
 e.KeyValue == 39)
                //方法0 当输入 37,39时
                return;

            if (e.KeyCode == Keys.F2)
            {
                //方法1 当键盘 输入 F2时
                return;
            }

            if (e.KeyCode == Keys.Enter)
            {
                //方法2当键盘 输入 F2时
                return;
            }

            if (sender == textBox1 && e.KeyCode == Keys.Enter)
            {
                //方法3 在控件 textBox1里 输入 回车
                return;
            }
            else if (sender == textEdit_Depart_area_name )
            {
                //方法4 在 控件 textEdit_Depart_area_name 时 
                return;
            }
}

[解决办法]

BindingFlags myBindingFlags = BindingFlags.Static 
[解决办法]
 BindingFlags.Instance 
[解决办法]
 BindingFlags.Public 
[解决办法]
 BindingFlags.NonPublic;
            Type t = typeof(System.Windows.Forms.Control);
            EventInfo ei = btnInsert.GetType().GetEvent("KeyUp", myBindingFlags);

            FieldInfo fi = t.GetField("EventClick", myBindingFlags);

            EventHandlerList ehl = btn.GetType().GetProperty("Events", BindingFlags.Instance 
[解决办法]
 BindingFlags.NonPublic 
[解决办法]
 BindingFlags.FlattenHierarchy).GetValue(btn, null) as EventHandlerList;

            if (ehl != null)
            {
                Delegate d = ehl[fi.GetValue(btn)];
                if (d != null&&d.GetInvocationList().Count()>0)
                {
                    //已绑定                    
                }


            }


[解决办法]
的确,无法直接用 != , == 判断。
因为 Control.KeyDown 重新包装了,只有 add 和 remove
[SRDescription("ControlOnKeyDownDescr"), SRCategory("CatKey")]
public event KeyEventHandler KeyDown
{
    add
    {
        base.Events.AddHandler(EventKeyDown, value);
    }
    remove
    {
        base.Events.RemoveHandler(EventKeyDown, value);
    }
}

如果你自定义的事件:
public event KeyEventHandler MyEvent;
这样就可以通过 != / == 判断是否添加过 Handler 

建议lz换个思路判断,比如将 KeyDown 绑定到一个 DispatchedHandler 上
在 Dispatcher 里判断调用不同的方法。

如果一定要通过 != / == 判断也可以用反射:
var bindingFlags = System.Reflection.BindingFlags.Static 
[解决办法]
 System.Reflection.BindingFlags.NonPublic;
var eventKeyDown = typeof(Control).GetField("EventKeyDown", bindingFlags).GetValue(null);
KeyEventHandler handler = (KeyEventHandler)base.Events[eventKeyDown];
if (handler != null)
    MessageBox.Show("Has Handler");
else
    MessageBox.Show("Not Handler");



 

[解决办法]
现写了一段代码,可实现楼主需求。

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 TestKeyUp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        int iEventID = 0;
        
        delegate void MyKeyUp(object o, KeyEventArgs k);
        event MyKeyUp OldEvent;
        private void Form1_Load(object sender, EventArgs e)
        {
            SaveEvent();                                                           
        }
        private void Form1_KeyUpA(object sender, KeyEventArgs e)
        {
            MessageBox.Show("A");
            iEventID++;
            SaveEvent();   
        }
        private void Form1_KeyUpB(object sender, KeyEventArgs e)
        {
            MessageBox.Show("B");
            iEventID++;
            SaveEvent();   
        }
        private void Form1_KeyUpC(object sender, KeyEventArgs e)
        {
            MessageBox.Show("C");
            iEventID = 0;
            SaveEvent();   
        }
        private void SaveEvent()
        {
            switch (iEventID)
            {
                case 0:
                    if (OldEvent != null)
                    {


                        this.KeyUp -= new System.Windows.Forms.KeyEventHandler(OldEvent);
                    }
                    OldEvent = this.Form1_KeyUpA;
                    this.KeyUp += new System.Windows.Forms.KeyEventHandler(OldEvent);
                    break;
                case 1:
                    this.KeyUp -= new System.Windows.Forms.KeyEventHandler(OldEvent);
                    OldEvent = this.Form1_KeyUpB;
                    this.KeyUp += new System.Windows.Forms.KeyEventHandler(OldEvent);
                    break;
                case 2:
                    this.KeyUp -= new System.Windows.Forms.KeyEventHandler(OldEvent);
                    OldEvent = this.Form1_KeyUpC;
                    this.KeyUp += new System.Windows.Forms.KeyEventHandler(OldEvent);
                    break;
            } 
        }
    }
}


[解决办法]
还有个方法,重写 OnKeyDown 引发一个自定义的事件。
你的Handler都绑定到你自定义事件上,这样通过自定义事件的 != null 也可以处理。



[解决办法]
注意,以下描述均需要反射进行操作。

System.Windows.Forms.Control的非公共成员中的静态变量中有许多这样类似的数据:
EventClick{object}object
EventClientSize{object}object
EventContextMenu{object}object
EventContextMenuStrip{object}object
EventControlAdded{object}object
EventControlRemoved{object}object
EventCursor{object}object
EventDock{object}object
EventDoubleClick{object}object
EventDragDrop{object}object
EventDragEnter{object}object
EventDragLeave{object}object
EventDragOver{object}object
EventEnabled{object}object
EventEnabledChanged{object}object
EventEnter{object}object
EventFont{object}object
EventForeColor{object}object
EventGiveFeedback{object}object
EventGotFocus{object}object

他们均是以object类型存储的,
在你需要查询的控件Button的继承对象:
System.Windows.Forms.ButtonBase -->
System.Windows.Forms.Control -->
System.ComponentModel.Component -->
System.MarshalByRefObject -->


中的一个非公共属性“Events {System.ComponentModel.EventHandlerList}”中存储了所有的事件列表,他们存储的数据都在非公共属性中,还是继续使用反射才可以取得他们。
第一个事件在“head {System.ComponentModel.EventHandlerList.ListEntry}”中,head对象的属性“key {object}”就是上面的那些object, 
head对象的属性“handler”中的“_invocationList {object[]}”属性便是所有事件的列表

head对象的“next {System.ComponentModel.EventHandlerList.ListEntry}”属性为下一个委托列表,如果为null,那么没有委托,next对象与head的内容格式完全相同
[解决办法]
http://topic.csdn.net/t/20050728/08/4172839.html
这里的解决办法应该可以。

热点排行