本文实例讲述了ASP.NET中实现定制自己的委托和事件参数类的方法,对于学习ASP.NET有很好的参考借鉴价值。具体方法如下:
一般在实际开发中,对于事件不需要传递数据信息时,像上面的KingTextBox控件的事件,在引发事件时传递的参数为EventArgs.Empty,如下所示:
OnTextChanged(EventArgs.Empty);
这是因为控件KingTextBox的TextChanged事件比较简单,这里不需要参数对象传递数据。但像一些复杂的控件比如GridView的按钮命令事件,必须得有参数命令表示单击了哪个按钮;翻页事件,需要EventArgs参数对象把当前页信息传递到页面后台代码的事件体的第二个参数中,然后开发人员根据此页参数从数据库取得对应页的数据;还有像ItemDataBound事件,也需要把当前Row信息和索引等数据作为EventArgs参数传递到事件实例中。
当遇到以上这些情况,我们就需要定义自己的事件参数类和委托,而不使用默认的System.EventArgs类。下面就以Grid控件的翻页功能说明一下定义事件参数类和委托的方法,请看以下代码:
/// <summary> /// /// </summary> public delegate void GridPageChangedEventHandler(object source, GridPage ChangedEventArgs e); public class GridPageChangedEventArgs : System.EventArgs { public GridPageChangedEventArgs() { } private int intCurrentPageIndex; public new int CurrentPageIndex { get { return intCurrentPageIndex; } set { intCurrentPageIndex = value; } } private int intPageCount; public new int PageCount { get { return intPageCount; } set { intPageCount = value; } } private int intPageSize; public new int PageSize { get { return intPageSize; } set { intPageSize = value; } } }
以上代码定义了一个存储翻页相关信息的参数类,此参数类派生于System.EventArgs类,在这里系统不强制要求一定继承于该类,不继承它也是可以的,但继承于该类有一点好处。先看一下System.EventArgs基类的代码:
/// <summary> /// /// </summary> public class EventArgs { //表示没有事件数据的事件 public static readonly EventArgs Empty; //初始化 System.EventArgs 类的新实例 public EventArgs(); }
EventArgs中除了一个构造方法外,还有一个它本身类型的Empty属性,从这里可以知道前面在调用时通过OnTextChanged(EventArgs.Empty);格式,把EventArgs.Empty作为空参数传入事件引发方法时的用途了。这里要说明的是如果我们的GridPageChangedEventArgs类是从EventArgs继承而来,则不但可以传递GridPageChangedEventArgs类对象,而且可以使用GridPageChangedEventArgs.Empty的形式传递空参数对象。
在GridPageChangedEventArgs方法体中定义了一些属性;分别表示当前页(CurrentPageIndex)、页总数(PageCount)和页尺寸(PageSize)。这些都是我们自定义的页信息数据。
代码中的这句:
public delegate void GridPageChangedEventHandler(object source, GridPage ChangedEventArgs e);
定义了一个委托GridPageChangedEventHandler。该委托可以指定这样的一个事件方法:第一个参数为object类型,第二个参数即为上面我们定义的页参数类对象GridPageChanged EventArgs。在注册事件时,该委托可以保证在页面后面代码中自动产生的事件体的两个参数类型与自己的两个参数类型一致。下面是在页面中注册的事件后台代码:
protected void Grid1_PageIndexChanged(object source,GridPageChangedEventArgs e) { int intCurrentPageIndex = e.CurrentPageIndex; int intPageSize = e.PageSize; //获取数据逻辑 }
可以看到第二个参数类型即我们定义的GridDocPageChangedEventArgs类型,在事件方法体中,可以直接通过e.CurrentPageIndex和e.PageSize获取数据,这种应用就比较多了。
现在页参数对象和委托定义好了,下面说一下在主控件内部是如何应用它们的。声明事件代码如下:
/// <summary> /// /// </summary> private new static readonly object EventPageIndexChanged = new object(); [Category("Action"), Description("翻页事件")] public event GridPageChangedEventHandler PageIndexChanged { add { base.Events.AddHandler(Grid.EventPageIndexChanged, value); } remove { base.Events.RemoveHandler(Grid.EventPageIndexChanged, value); } }
这里继续采用高效率事件集合列表对象base.Events,事件的名称为PageIndexChanged,委托类型为之前我们定义的委托类型GridPageChangedEventHandler。
引发事件的核心代码如下:
/// <summary> /// /// </summary> protected override bool OnBubbleEvent(object source, EventArgs e) { bool handled = false; if (e is GridCommandEventArgs) { if ((((GridCommandEventArgs)(e)).CommandSource) is LinkButton) { LinkButton lb=((LinkButton)(((GridCommandEventArgs)(e)). Command Source)); if (lb.CommandName == "Page") { if (lb.CommandArgument == "ButtonFirst") { GridPageChangedEventArgs ee = new GridPageChangedEventArgs(); if (this.CurrentPageIndex != 0) { this.CurrentPageIndex = 0; ee.CurrentPageIndex = this.CurrentPageIndex; ee.PageCount = this.PageCount; ee.PageSize = this.PageSize; this.OnPageIndexChanged(ee); } handled = true; } if (lb.CommandArgument == "ButtonNext") { GridPageChangedEventArgs ee = new GridPageChangedEventArgs(); if (this.CurrentPageIndex < this.PageCount - 1) { this.CurrentPageIndex += 1; ee.CurrentPageIndex = this.CurrentPageIndex; ee.PageCount = this.PageCount; ee.PageSize = this.PageSize; this.OnPageIndexChanged(ee); } handled = true; } if (lb.CommandArgument == "ButtonPrev") { GridPageChangedEventArgs ee = new GridPageChangedEventArgs(); if (this.CurrentPageIndex > 0) { this.CurrentPageIndex -= 1; ee.CurrentPageIndex = this.CurrentPageIndex; ee.PageCount = this.PageCount; ee.PageSize = this.PageSize; this.OnPageIndexChanged(ee); } handled = true; } if (lb.CommandArgument == "ButtonLast") { GridPageChangedEventArgs ee = new GridPageChangedEventArgs(); if (this.CurrentPageIndex != this.PageCount - 1) { this.CurrentPageIndex = this.PageCount - 1; ee.CurrentPageIndex = this.CurrentPageIndex; ee.PageCount = this.PageCount; ee.PageSize = this.PageSize; this.OnPageIndexChanged(ee); } handled = true; } } } } return handled || base.OnBubbleEvent(source, e); }
以上OnBubbleEvent方法主要应用于复合控件中,采用冒泡形式处理子控件事件,后面介绍复合控件冒泡处理事件机制时再详细讲解此方法。另外,在控件的翻页栏中预先放置了四个翻页功能的按钮,分别表示“首页”、“上一页”、“下一页”、“末页”,并设置它们的属性CommandName都为“Page”,CommandArgument分别为“ButtonFirst”,“ButtonPrev”,“ButtonNext”,“ButtonLast”。
这样就可以根据按钮的命令和参数确定执行什么样的逻辑。这里仅拿按钮“下一页”(Command="Page"&&CommandArgument="ButtonNext")为例解释一下代码逻辑:
/// <summary> /// /// </summary> if (lb.CommandArgument == "ButtonNext") { GridPageChangedEventArgs ee = new GridPageChangedEventArgs(); if (this.CurrentPageIndex < this.PageCount - 1) { this.CurrentPageIndex += 1; ee.CurrentPageIndex = this.CurrentPageIndex; ee.PageCount = this.PageCount; ee.PageSize = this.PageSize; this.OnPageIndexChanged(ee); } handled = true; }
代码中首先定义一个页参数类对象,然后通过条件语句判断当前是否是最后一页,如果不是最后一页,则从主控件上读取当前页信息(当前页、页数、页记录数),并赋值给GridPageChangedEventArgs对象,然后以页参数对象作为参数调用this.OnPageIndexChanged方法引发事件。另外,注意LinkButton的CommandName和CommandArgument属性的组合用法。
最后,看一下OnPageIndexChanged方法代码:
/// <summary> /// </summary> protected new void OnPageIndexChanged(GridPageChangedEventArgs e) { GridPageChangedEventHandler handler1 = (GridPageChangedEventHandler)base. Events[Grid.EventPageIndexChanged]; if (handler1 != null) { handler1(this, e); } }
此方法的功能是从base.Events对象中取出以Grid.EventPageIndexChanged为Key的事件引用句柄,假如句柄不为null(开发人员注册了翻页事件),则引发事件方法体。
最后,说明非常重要的一点:如果自定义了事件参数类,并要求在开发人员注册的事件体中自动显示改变参数对象的类型,如:
protected void Grid1_PageIndexChanged(object source, GridPageChangedEventArgs e) { //… … }
其中的第二个参数显示为GridPageChangedEventArgs类型,而不是默认的EventArgs类型,我们也必须定义自己的委托(如本例定义了委托GridPageChangedEventHandler);而默认的委托EventHandler对应的参数类型为基类System.EventArgs,即如果这里将默认的委托EventHandler和GridPageChangedEventArgs类一起使用的话,则生成以下的代码语句:
protected void Grid1_PageIndexChanged(object source, EventArgs e) { //… … }
可以看出参数变为EventArgs类型了。这样就不能利用我们自己定义的GridPage ChangedEventArgs类中的数据了。虽然可以使用(GridPageChangedEventArgs)EventArgs的方式转换一下也可以取得GridPageChangedEventArgs对象中的数据,但据笔者了解还没有开发人员这么用,因为没有人知道还有个GridPageChangedEventArgs类。
本文主要讲解如何定制自己的参数类和委托,并以Grid的分页功能为例演示其在实际开发中的应用。
感兴趣的读者可以参考本文所述调试运行本文示例,相信会有新的收获。
实现on,off的事件委托! 我们能根据之前的思路,利用同样的方法实现一个事件委托. 先来看看流程图 然后先看看结果是如何,毕竟流程图看的也不一定能懂。 最后我们再来看看代码 Kodo.deleEvents = []; //事件委托存放的事件 Kodo.deleId = 0; //事件委托的唯一标识 on: function(type, selector, fn) { if (typeo
本文向大家介绍jQuery事件绑定和委托实例,包括了jQuery事件绑定和委托实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery事件绑定和委托。分享给大家供大家参考。具体方法如下: jQuery事件的绑定和委托可以用多种方法实现,on() 、 bind() 、 live() 、 delegate() ,还有one()。 有时我们可能会像下面这样绑定一个事件: 上面的
捕获和冒泡允许我们实现一种被称为 事件委托 的强大的事件处理模式。 这个想法是,如果我们有许多以类似方式处理的元素,那么就不必为每个元素分配一个处理程序 —— 而是将单个处理程序放在它们的共同祖先上。 在处理程序中,我们获取 event.target 以查看事件实际发生的位置并进行处理。 让我们看一个示例 —— 反映中国古代哲学的 八卦图。 如下所示:在新窗口中打开 在沙箱中打开 其 HTML 如
本文向大家介绍C#中的委托是什么?事件是不是一种委托?事件和委托的关系。相关面试题,主要包含被问及C#中的委托是什么?事件是不是一种委托?事件和委托的关系。时的应答技巧和注意事项,需要的朋友参考一下 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的指针。 委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实
主要内容:为什么要使用事件委托,事件委托实现原理,事件委托的优点,总结利用 JS 事件冒泡动态为元素绑定事件的方法称为事件委托(Event Delegation,也称为“事件代理”),是 JavaScript 中最热门的技术之一。 事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。 举个简单的例子,整个宿舍的同学都需要去取快递,一种方法是让他们
问题内容: 我已经开始尝试创建普通的MVC Swing组件。我对M和C没问题,但是V向我抛出了一个我通常无法解决的问题。问题是:控制器是组件的主类(例如MyComponent),并且它扩展了JComponent。视图是从ComponentUI类扩展的ui委托(MyCompanentUI)。委托所做的只是在MyCompanent中添加JTextField并提供MyComponentModel与该字段