ASP.NET中实现定制自己的委托和事件参数类

 更新时间:2021年9月22日 10:11  点击:2068

本文实例讲述了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的分页功能为例演示其在实际开发中的应用。

感兴趣的读者可以参考本文所述调试运行本文示例,相信会有新的收获。

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • C#事件(event)使用方法详解

    本文给大家介绍了在C#中,事件(event)的概念和使用方法,文章适合一些初学者学习,主要讲解了一些概念和一些代码案例。...2020-06-25
  • jQuery事件绑定用法详解(附bind和live的区别)

    这篇文章主要介绍了jQuery事件绑定用法,结合实例形式较为详细的分析了jQuery事件绑定的实现原理与相关注意事项,并附带了相关绑定方法的使用说明,重点介绍了bind和live的区别,需要的朋友可以参考下...2016-01-21
  • C#基于委托实现多线程之间操作的方法

    这篇文章主要介绍了C#基于委托实现多线程之间操作的方法,实例分析了C#的委托机制与多线程交互操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • easyUI下拉列表点击事件使用方法

    这篇文章主要为大家详细介绍了easyUI下拉列表点击事件的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-05-22
  • C#事件实例详解

    这篇文章主要介绍了C#事件实例详解的相关资料,需要的朋友可以参考下...2020-06-25
  • jQuery Mobile 触摸事件实例

    这篇文章主要演示了5个jQuery Mobile 触摸事件实例,需要的朋友可以参考下。...2016-06-12
  • 详解C#中委托,事件与回调函数讲解

    这篇文章主要介绍了详解C#中委托,事件与回调函数讲解,小编觉得挺不错的,现在就分享给大家,也给大家做个参考。...2020-06-25
  • jQuery绑定事件监听bind和移除事件监听unbind用法实例详解

    这篇文章主要介绍了jQuery绑定事件监听bind和移除事件监听unbind用法,结合实例形式详细分析了绑定事件监听bind和移除事件监听unbind的具体使用技巧与相关注意事项,需要的朋友可以参考下...2016-01-21
  • 详解ASP.NET Core 中基于工厂的中间件激活的实现方法

    这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • 详解C#之事件

    这篇文章主要介绍了C#之事件的知识点,文中代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以参考下...2020-06-25
  • python编程PyQt5创建按钮及触发点击事件示例解析

    这篇文章主要为大家介绍了python编程使用PyQt5如何创建按钮及触发点击事件的示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...2021-10-29
  • asp.net通过消息队列处理高并发请求(以抢小米手机为例)

    这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • javascript监听鼠标滚轮事件浅析

    我们都见到过这些效果,用鼠标滚轮实现某个表单内的数字增加减少操作,或者滚轮控制某个按钮的左右,上下滚动。这些都是通过js对鼠标滚轮的事件监听来实现的。今天这里介绍的是一点简单的js对于鼠标滚轮事件的监听。不同浏...2014-06-07
  • C#移除所有事件绑定的方法

    这篇文章主要介绍了C#移除所有事件绑定的方法,实例分析了C#事件绑定的移除方法,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • ASP.NET单选按钮控件RadioButton常用属性和方法介绍

    RadioButton又称单选按钮,其在工具箱中的图标为 ,单选按钮通常成组出现,用于提供两个或多个互斥选项,即在一组单选钮中只能选择一个...2021-09-22
  • ASP.NET 2.0中的数据操作:使用两个DropDownList过滤的主/从报表

    在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有...2016-05-19