您的位置:首页 > 编程语言 > C#

C#开发学习笔记:动态绑定控件事件

2016-07-26 09:01 711 查看
如何实现窗体中的按钮根据不同要求动态绑定不同的事件

1.首先可以新建一个类,在类中创建一个方法,该方法需要一个参数,为了方便可以直接传窗体对象,这样不管是想对窗体上的任何

控件进行动态绑定事件都可以直接获取到需要的控件

public static void SetStatusButtonEvent(Form form)
2.获取到相应的控件之后,将控件强转为原来的控件类型

BarLargeButtonItem lagerbutton = ItemLink.Item as BarLargeButtonItem;

3.通过指定的事件获取获取按钮相关事件的事件对象
EventInfo eventInfo = lagerbutton.GetType().GetEvent("ItemClick",BindingFlags.Public | BindingFlags.Instance);注:GetEvent方法中的第一个参数代表事件名,第二个参数的参数说明是一个位屏蔽,不知道具体代表什么,个人感觉就是通过Public和Instance
这两个修饰符来搜索相应类型的方法,这个参数具体意义可以通过个人理解,而GetEvent这个方法就是用来获取EventHandlerType(事件句柄类型)

EventInfo类型表示发现事件的属性并提供对事件元数据的访问权.

4,绑定事件

MethodInfo doEventMethod = form.GetType().GetMethod(EventName,BindingFlags.NonPublic | BindingFlags.Instance);定义一个MethodInfo类型的变量,GetMethod方法是使用指定绑定约束搜索自定方法,两个参数和上面GetEvent()方法一样的,这个方法是用来获取
需要绑定到控件上面的方法(根据你提供的方法名和要搜索的类型去搜索)

5,创建一个委托

ItemClickEventHandler d = (ItemClickEventHandler)Delegate.CreateDelegate(eventInfo.EventHandlerType, form, doEventMethod);

这个变量类型的定义需要根据事件是事件触发类型来确定,CreateDelegate()创建委托,第一个参数就是要绑定的事件类型(每个事件都有指定的类型)
第二个参数,这里特别说明一下,这个参数表示要将委托绑定到的对象,可以为null,但是我不知道在什么样的情况下可以为null,为null时,后面的方法会被

当做static类型的方法,我在这里填的是form(窗体),一开始我这里t填写的是null,但是这样在后面测试时发现一个问题,当我触发事件之后,在事件内部

获取不到当前窗体的对象(this为null)而且获取不到任何窗体上的控件,后来发现我这里填写null时,创建个委托的target属性为null,我就用其他的事件

试了一下,其他事件的target都是指向到窗体的,所以我就把这里改为窗体对象,测试时一切正常

6.绑定委托到对象(这里和上面的CreateDelegate()的第二个参数的意思不一样)

eventInfo.AddEventHandler(lagerbutton, d);
AddEventHandler()将事件处理程序添加到事件源(触发事件的控件),第一个参数代表的就是事件源,第二个参数就是事件
这句话相当于lagerbutton.ItemClick+=new ItemClickEventHandler(事件名);
以上就是动态订阅事件的步骤,下面是我自己写的动态订阅的全部代码

using DevExpress.XtraBars;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RC
{
/// <summary>
/// 窗体底部按钮事件绑定专用类
/// </summary>
public class RCBindingEvent
{

#region 动态订阅事件
/// <summary>
/// 动态绑定F1-F12按钮事件(窗体底部功能按钮专用)
/// </summary>
/// <param name="form">当前窗体对象</param>
public static void SetStatusButtonEvent(Form form)
{
foreach (Control control in form.Controls)
{
Type type = control.GetType();
if (type.Name == "RCStatusButton")
{
RC.RCStatusButton item = control as RC.RCStatusButton;
string itemName = item.Name;
foreach (BarItemLink ItemLink in item.bar3.ItemLinks)
{
BarLargeButtonItem lagerbutton = ItemLink.Item as BarLargeButtonItem;
if (lagerbutton != null)
{
int a = lagerbutton.Id;
try
{
//下面的代码主要解决如何动态订阅事件

EventInfo eventInfo = lagerbutton.GetType().GetEvent("ItemClick",
BindingFlags.Public | BindingFlags.Instance);
BarButtonStyle aaa = lagerbutton.ButtonStyle;
string EventName = "";
if (lagerbutton.Name != "OKStatusButton" &&
lagerbutton.Name != "CancelStatusButton"&&
lagerbutton.Description=="Default")
EventName = form.Name + "_RC_OK_" + lagerbutton.Name;
else
EventName = form.Name + "_RC_PRE_" + lagerbutton.Name;
MethodInfo doEventMethod = form.GetType().GetMethod(EventName,
BindingFlags.NonPublic | BindingFlags.Instance);
if (doEventMethod != null)
{
//此处第二个参数一开始写的是null,导致虽然绑定了事件,但是事件触发之后获取不到事件所在的窗体的对象信息
//是由于第二个参数表委托要绑定到的对象,这个对象具体怎么定义不知道,但是委托都有一个method属性和target属性
//如果此处填null则创建的委托target属性为null,target为null就导致事件绑定到button上之后,在窗体中触发事件时
//this(代表当前窗体)为null,表示窗体对象为null相当于窗体不存在,因此,个人理解CreateDelegate方法的第二个参数
//所定义的委托要绑定到的对象中的对象代表的就是窗体
ItemClickEventHandler d = (ItemClickEventHandler)Delegate.CreateDelegate(eventInfo.EventHandlerType, form, doEventMethod);
eventInfo.AddEventHandler(lagerbutton, d);
//lagerbutton.PerformClick(ItemLink);//这句代码用于立即执行事件
}
if (lagerbutton.Name == "OKStatusButton" || lagerbutton.Name == "CancelStatusButton")
lagerbutton.Enabled = false;
}
catch (Exception)
{

throw;
}
}
}
}
}
}

#endregion

}
}


以上内容,纯属本人自己总结,如有雷同纯属巧合.

以上内容,纯属本人自己总结,如有不对请大神赐教.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: