在之前讲的几个例子中,使用的是最普通的定义事件方法,比如KingTextBox中事件是这样定义的:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
public event EventHandler TextChanged;
protected virtual void OnTextChanged(EventArgs e)
{
    if (TextChanged != null)
    {
        TextChanged(this, e);
    }
}
在复合控件中,事件一般比较多,如果仍然基于以上普通事件的实现方法来定义事件,就会定义许多事件委托实现对象,导致占用较多内存存储。
在这种情况下,则应该通过System.ComponentModel.EventHandlerList集合类来保存事件,原因是使用此类在多个事件的声明过程中比普通的实现方法效率高。EventHandlerList类提供一个简单的委托列表来添加(Events.AddHandler)和删除(Events.RemoveHandler)委托,在Control基类中已经定义好了EventHandlerList类型的对象Events,因此可以直接通过base.Events访问事件列表对象。
下面利用Events集合对象存储事件,修改一下KingTextBox控件的事件声明/调用部分,为了保留KingTextBox现有功能,新增一个控件示例,控件名称为KingTextBoxUseEvents。事件部分的代码为:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>

private static readonly object TextChangedKeyObject = new object();
public event EventHandler TextChanged
{
    add
    {
        base.Events.AddHandler(KingTextBoxUseEvents.TextChangedKeyObject, value);
    }
    remove
    {
        base.Events.RemoveHandler(KingTextBoxUseEvents.TextChangedKeyObject, 
        value);
    }
}
protected virtual void OnTextChanged(EventArgs e)
{
    EventHandler handler = base.Events[KingTextBoxUseEvents.TextChanged 
    KeyObject] as EventHandler;
    if (handler != null)
    {
        handler(this, e);
    }
}
以上代码首先定义了一个Object对象TextChangedKeyObject,用于当存储事件到Events列表时,作为TextChanged事件的Key,其对应Value为即为事件方法体。接下来定义了一个事件委托类型的TextChanged属性,其内容包括一个add和一个remove子句,在这两个子句中分别完成注册和释放事件功能。最后的OnTextChanged方法也稍微变了一下,增加了从base.Events事件列表中根据TextChangedKeyObject键得到事件句柄的代码语句,如果取得的句柄handler不为null,即可引发开发人员注册的事件。
控件KingTextBoxUseEvents代码也比较简单,下面也把它的完整代码展示出来:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
[DefaultProperty("Text")]
[ToolboxData("<{0}:KingTextBoxUseEvents runat=server></{0}:KingTextBoxUseEvents>")]
public class KingTextBoxUseEvents : Control, IPostBackDataHandler
{
    public KingTextBoxUseEvents()
    {
    }

/// <summary>
    /// 设置或获取显示文本
    /// </summary>        
    public string Text
    {
        get
        {
            String s = (String)ViewState["Text"];
            return ((s == null) ? String.Empty : s);
        }

set
        {
            ViewState["Text"] = value;
        }
    }

/// <summary>
    /// 生成呈现HTML格式标记
    /// </summary>
    /// <param name="writer"></param>
    protected override void Render(HtmlTextWriter writer)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("<input type=/"text/" name=");
        sb.Append("/"" + UniqueID + "/"");
        sb.Append(" value=");
        sb.Append("/"" + HttpUtility.HtmlEncode(Text) + "/"");
        sb.Append(" />");
        writer.Write(sb.ToString());
    }

public virtual bool LoadPostData(string postDataKey, NameValueCollection 
    postCollection)
    {
        string strOldValue = Text;
        string strNewValue = postCollection[this.UniqueID];
        if( strOldValue == null || ( strOldValue != null && !strOldValue.Equals 
        (strNewValue)))
        {
            this.Text = strNewValue;
            return true;
        }
        return false;
    }

public virtual void RaisePostDataChangedEvent()
    {
        OnTextChanged(EventArgs.Empty);
    }

//高效事件
    private static readonly object TextChangedKeyObject = new object();
    public event EventHandler TextChanged
    {
        add
        {
            base.Events.AddHandler(KingTextBoxUseEvents.TextChangedKeyObject, value);
        }
        remove
        {
            base.Events.RemoveHandler(KingTextBoxUseEvents.TextChanged 
            KeyObject, value);
        }
    }
    protected virtual void OnTextChanged(EventArgs e)
    {
        EventHandler handler =base.Events[KingTextBoxUseEvents.TextChanged KeyObject] as EventHandler;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}
KingTextBoxUseEvents控件与KingTextBox功能完全相同,应用方法也相同。另外,事件的委托和参数对象也可以自定义,下一节就讲一下如何定制自己的委托和事件对象。

《纵向切入ASP.NET 3.5控件和组件开发技术》笔记:高效率事件集合对象的更多相关文章

  1. ASP.NET 3.5控件和组件开发技术之客户端回发/回调揭密

    本文摘录自<纵向切入ASP.NET 3.5控件和组件开发技术>. 对于服务端控件元素,比如ASP.NET的Button标准服务端控件在提交时可以自动把请求发送到服务端处理,这样的控件我们不 ...

  2. [转载]ASP.NET中TextBox控件设立ReadOnly="true"后台取不到值

    原文地址:http://www.cnblogs.com/yxyht/archive/2013/03/02/2939883.html ASP.NET中TextBox控件设置ReadOnly=" ...

  3. ASP.NET Web数据控件

    ASP.NET Web数据控件 1.数据控件简介 这包括数据源控件和格式设置控件,前者使您可以使用 Web 控件访问数据库中的数据,后者使您可以显示和操作ASP.NET 网页上的数据.  2.数据控件 ...

  4. 027. asp.net中数据绑定控件之 GridView控件

    GridView控件支持下面的功能: 绑定至数据源控件, 如SqlDataSource 内置排序功能 内置更新和删除功能 内置分页功能 内置行选择功能 可以编程方式访问GridView对象模型以动态设 ...

  5. ASP.NET让FileUpload控件支持浏览自动上传功能的解决方法

    ASP.NET的FileUpload控件默认是不支持服务端的onchange事件的,此时可以用一种变通的方法来实现这一功能. 这就需要借用客户端的onchange事件,调用__doPostBack方法 ...

  6. 关于ASP.net TextBox控件的失去焦点后触发其它事件

    编写人:CC阿爸 2015-2-02 今天在这里,我想与大家一起分享如何处理的ASP.net TextBox控件的失去焦点后触发其它事件的问题,在此做个小结,以供参考.有兴趣的同学,可以一同探讨与学习 ...

  7. (九)ASP.NET自定义用户控件(2)

    http://www.cnblogs.com/SkySoot/archive/2012/09/04/2670678.html 用户控件 在 .NET 里,可以通过两种方式把自己的控件插入到 Web 窗 ...

  8. asp.net中Repeater控件用法笔记

    大家可能都对datagrid比较熟悉,但是如果在数据量大的时候,我们就得考虑使用 repeater作为我们的数据绑定控件了.Repeater控件与DataGrid (以及DataList)控件的主要区 ...

  9. 【转】ASP.NET常用数据绑定控件优劣总结

    转自:http://www.cnblogs.com/Olive116/archive/2012/10/24/2736570.html ASP.NET常用数据绑定控件优劣总结   本文的初衷在于对Asp ...

随机推荐

  1. git clone https

    git clone 不需要输入密码步骤 1, vim ~/.git-credentials 2, git config --global credential.helper store 3, vim ...

  2. 什么情况下调用doGet()和doPost()?

    Jsp页面中的FORM标签里的method属性为get时调用doGet(),为post时调用doPost().

  3. Xamarin 2017.9.13发布更新

     Xamarin 2017.9.13发布更新 Visual Studio 2017更新到15.3.4.其中,Xamarin.Visual更新到4.6.3.4;Xamarin.iOS更新到10.12.3 ...

  4. 关于django 京东淘宝 混合搜索实现原理

    混合搜索在各大网站如京东.淘宝都有应用,他们的原理都是什么呢?本博文将为你介绍它们的实现过程. 混合搜索的原理,用一句话来说就是:关键字id进行拼接. 混合搜索示例: 数据库设计: 视频方向: 1 2 ...

  5. React Native 系列(四)

    前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...

  6. Scrapy实战篇(五)爬取京东商城文胸信息

    创建scrapy项目 scrapy startproject jingdong 填充 item.py文件 在这里定义想要存储的字段信息 import scrapy class JingdongItem ...

  7. [BZOJ1040][ZJOI2008]骑士(环套树dp)

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5816  Solved: 2263[Submit][Status ...

  8. 【20181026T2】**图【最小瓶颈路+非旋Treap+启发式合并】

    题面 [错解] 最大最小?最小生成树嘛 蛤?还要求和? 点分治? 不可做啊 写了个MST+暴力LCA,30pts,140多行 事后发现30分是给dijkstra的 woc [正解] 树上计数问题:①并 ...

  9. PHP -- 页面传值的6种获取方法

    1.PHP4以后获取传值的方法 一般在页面中传值常见的是POST.GET和COOKIE几种,所以下面我也主要介绍这几种.PHP4以后都采用的是$_POST.$_GET等数组来获取网页传值.在PHP3. ...

  10. iOS防止button重复点击

    项目中常会遇到在按钮的点击事件中去执行一些耗时操作.如果处理不当经常会出现连续多次点击push多次的情况,造成不好的用户体验. 一种情况是用户快速连续点击,这种情况无法避免.另一种情况是点击一次后响应 ...