• ASP.NET 控件开发之旅(一)


      很多朋友都在问.NET控件开发 到底有多难(看到很多博友发自己的一些控件,我在想自己开发的就有好几十个了,与其一个个发,不如直接讲给大家听如何开发的,同时在讲解的过程把一些控件发给大家呵呵),其实可以轻松的告诉大家有恒心就能成绩来着,最好的控件全部在你身边,想开发高效好用的空间那就必须参考微软本身优秀的控件.为此我们手头要有一个好的工具Reflector.exe,这个大名鼎鼎的Reflector 你还不知道的话,只能被笑话了(窃笑),好了 大家伙自己百度谷歌找下,然后继续我们的文章,对于控件的使用我初略的给.NET 控件使用开发人员分了一个等级:

    1.       会使用ASP.NET 控件(简单的自定义控件,还有服务器控件),对事件=其他知识完全没有概念

    2.       掌握了页面事件的初步框架,能在不同事件中处理控件逻辑

    3.       开发控件,运用属性以及理解HtmlTextWriter 输出的基本特性

    4.       开发复杂控件,整合CSS,JS 以及缓存,主题==各种功能的 综合性控件

    看看你自己处于那个阶段,是不是还停留在只会用用GridView ==控件的一些初级阶段呢?其实想摆脱现状就必须从整个页面事件去了解,对于页面事件我会在接下来的文章好好给大家分析来着.

     通过本文希望大家从控件开发中,深入理解 .NET 页面事件,以及各种控件开发中的设计模式(其实透过.NET FRAMEWORK中的Controls类的设计就能明白微软的意图),以及委托在事件中的使用,和一些基本的正则使用.当然最后是控件的完美开发咯

    废话不多说.先给大家分析一个 我们经常用到的控件ASP.NET Button 控件

    我们打开Reflector找到 System.Web.UI.WebControls这个命名控件,然后找到Button控件,我们展开

     

    3.bmp

     

    4.bmp找到Button 控件, 然后继续展开Button,

    我这里和大家讲讲分别是什么意思就好了  其他的大家自己去看了 不过不理解的 我们可以一起讨论,还可以为你解释一下,那些控件我基本通看了一下 嘿嘿

    Base Types 是他的基本类型,Derived Types 是他的派生类,红色的那些图标是她的 方法,带有手的图标是 属性,闪电的图标是 事件 ,.ctor() 就是构造函数 cctor 就是静态构造函数,EventClick , EventCommand 是类成员 .好了 基本就这样了 大家有什么不明白的可以在这里提问,我也会及时回答的.其实 Button 控件包含的意义很深,看明白了 对以后的控件开发有很大的帮助

    比如他的

    Code

     

    AddAttributesToRender这个方法 就很好的展示给大家 ASP.NET 只如何处理INPUT 各种属性的呢.

     

    下面分享我开发工程中的一个控件

    这个控件是支持Url 分页的

    当然 原理 是利用IList 的索引 取不同的数据 对于偷懒和后台管理很方便,至于前台的分页我想你更喜欢用存储过程 ROW_NUMBER() IDENTITY 方案来分页吧

     

     

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Text;

    using System.Web;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using System.Text.RegularExpressions;

    using System.Collections;

     

    namespace YSMV.XWShop1B2C.Control

    {

        [DefaultProperty("Text")]

        [ToolboxData("<{0}:YsmvRepeater runat=\"server\" AllowPage=\"true\" PageSize=\"10\" ShowPage=\"true\"></{0}:YsmvRepeater>")]

        public class YsmvRepeater : Repeater

        {

          

            //Static param

            private static readonly Regex RX;

            private static readonly object EventPageChanged;

     

            static YsmvRepeater()

            {

                RX = new Regex(@"^&page=\d+", RegexOptions.Compiled);

                EventPageChanged = new object();

            }

     

            //Static constants

            protected const string HTML1 = "<table cellpadding=0 cellspacing=0 class='inputTable'><tr><td colspan=2>";

            protected const string HTML2 = "</td></tr><tr><td class=paging align=left>";

            protected const string HTML3 = "</td><td align=right class=paging>";

            protected const string HTML4 = "</td></tr></table>";

            private const string LINK_PREV = "<a href=?page={0}>&#060;&nbsp;Previous</a>";

            private const string LINK_MORE = "<a href=?page={0}>More&nbsp;&#062;</a>";

            private const string KEY_PAGE = "page";

            private const string COMMA = "?";

            private const string AMP = "&";

     

            protected string emptyText;

            private IList dataSource;

            private int pageSize = 10;

            private int currentPageIndex;

            private int itemCount;

            private bool allowPage = false;

            private bool showPage = true;

     

            [Browsable(true)

            , Category("Appearance"),

            DefaultValue(true),

            Description("是否显示翻页链接")

            ]

            public bool ShowPage

            {

                get { return showPage; }

                set { showPage = value; }

            }

            [Browsable(true),

            Category("Appearance"),

            DefaultValue(true),

            Description("是否允许分页")]

            public bool AllowPage

            {

                get { return allowPage; }

                set { allowPage = value; }

            }

            [Browsable(true),

            Category("Appearance"),

            DefaultValue(10),

            Description("每页显示的数量")

            ]

            public int PageSize

            {

                get { return pageSize; }

                set { pageSize = value; }

            }

            [Browsable(true),

            Category("Appearance"),

            DefaultValue(""),

            Description("无记录时候显示的内容")]

            public string EmptyText

            {

                set { emptyText = value; }

            }

            override public object DataSource

            {

                set

                {

                    //This try catch block is to avoid issues with the VS.NET designer

                    //The designer will try and bind a datasource which does not derive from ILIST

                    try

                    {

                        dataSource = (IList)value;

                        ItemCount = dataSource.Count;

                    }

                    catch

                    {

                        dataSource = null;

                        ItemCount = 0;

                    }

                }

            }

            protected int PageCount

            {

                get { return (ItemCount - 1) / pageSize; }

            }

     

            virtual public int ItemCount

            {

                get { return itemCount; }

                set

                {itemCount = value;}

            }

     

            virtual public int CurrentPageIndex

            {

                get { return currentPageIndex; }

                set { currentPageIndex = value; }

            }

     

            public void SetPage(int index)

            {

                //OnPageIndexChanged(new DataGridPageChangedEventArgs(null, index));

                OnPageIndexChanged(new GridViewPageEventArgs(index));

            }

     

            override protected void OnLoad(EventArgs e)

            {

                if (Visible)

                {

                    string page = Context.Request[KEY_PAGE];

                    int index = (page != null) ? int.Parse(page) : 0;

                    SetPage(index);

                }

            }

     

            /// <summary>

            /// Overriden method to control how the page is rendered

            /// </summary>

            /// <param name="writer"></param>

            override protected void Render(HtmlTextWriter writer)

            {

     

                //Check there is some data attached

                string page = Context.Request[KEY_PAGE];

                int index = (page != null) ? int.Parse(page) : 0;

                if (ItemCount == 0)

                {

                    writer.Write(emptyText);

                    return;

                }

                //Mask the query

                string query = Context.Request.Url.Query.Replace(COMMA, AMP);

                query = RX.Replace(query, string.Empty);

     

                // Write out the first part of the control, the table header

                writer.Write(HTML1);

     

                // Call the inherited method

                base.Render(writer);

     

                // Write out a table row closure

                writer.Write(HTML2);

     

                //Determin whether next and previous buttons are required

                //Previous button?

                if (currentPageIndex > 0)

                {

                    if (ShowPage)

                        writer.Write(string.Format(LINK_PREV, (currentPageIndex - 1) + query));

                }

     

                //Close the table data tag

                writer.Write(HTML3);

     

                //Next button?

                if (currentPageIndex < PageCount)

                {

                    if (ShowPage)

                        writer.Write(string.Format(LINK_MORE, (currentPageIndex + 1) + query));

                }

     

                //Close the table

                writer.Write(HTML4);

            }

     

            override protected void OnDataBinding(EventArgs e)

            {

                if (!allowPage)

                {

                    base.DataSource = dataSource;

                    base.OnDataBinding(e);

                    return;

                }

                //Work out which items we want to render to the page

                int start = CurrentPageIndex * pageSize;

                int size = Math.Min(pageSize, ItemCount - start);

     

                IList page = new ArrayList();

     

                //Add the relevant items from the datasource

                for (int i = 0; i < size; i++)

                    page.Add(dataSource[start + i]);

     

                //set the base objects datasource

                base.DataSource = page;

                base.OnDataBinding(e);

     

            }

     

            //public event DataGridPageChangedEventHandler PageIndexChanged;

            public event GridViewPageEventHandler PageIndexChanged

            {

                add

                {

                    Events.AddHandler(EventPageChanged, value);

                }

                remove

                {

                    Events.RemoveHandler(EventPageChanged, value);

                }

            }

            virtual protected void OnPageIndexChanged(GridViewPageEventArgs e)

            {

                GridViewPageEventHandler pagehandler = (GridViewPageEventHandler)Events[EventPageChanged];

                if (pagehandler != null)

                    pagehandler(this, e);

            }

        }

    }

    代码已经加了注释,细心的朋友 可能发现和 PETSHOP 中的控件很相似 ,,我是用那个修改的,我优化了他的事件private static readonly object EventPageChanged; 呵呵 ,好的 大家期待我的下个作品吧.

     

  • 相关阅读:
    著名的二分查找的BUG
    C/C++ static用法
    浅谈C++虚函数
    git备忘(长久更新)
    【经典问题】最大子串和
    水波纹效果
    博客迁址 xpeng.scorpionstudio.com
    终于,我们的新产品Fotor Slideshow Maker上线了!!
    分享一款浏览器扩展--美图搜索-图片搜索工具
    分享网页微信防撤回插件
  • 原文地址:https://www.cnblogs.com/bhtfg538/p/1356522.html
Copyright © 2020-2023  润新知