上一节用了一个示例说明了Ajax在CS2中的一点简单的应用,这一节里着重探讨一下CS2中的Ajax的高级应用和实现原理,在了解Ajax的实现原理前我觉得有必要先了解一下aspx页面从请求到返回HTML都做了些什么,我想在了解了页面处理机制再来认识Ajax处理原理应该应该会很有帮助的,见下表:
| 序号 | 阶段 | 页面事件 | 可覆盖的方法 | 
| 1 | 页面初始化 | Init |   | 
| 2 | 加载视图状态 |   | LoadViewState | 
| 3 | 处理回发数据 |   | 任意实现 IPostBackDataHandler 接口的控件中的 LoadPostData 方法 | 
| 4 | 加载页面 | Load |   | 
| 5 | 回发更改通知 |   | 任意实现 IPostBackDataHandler 接口的控件中的 RaisePostDataChangedEvent 方法 | 
| 6 | 处理回发事件 | 由控件定义的任意回发事件 | 任意实现 IPostBackDataHandler 接口的控件中的 RaisePostBackEvent 方法  | 
| 7 | 页面显示前阶段 | PreRender |   | 
| 8 | 保存视图状态 |   | SaveViewState | 
| 9 | 显示页面 |   | Render | 
| 10 | 卸载页面 | Unload |   | 
此表从上到下为处理ASPX页面所经历的过程,现简单解说一下各过程处理的工作:
1.              在页面实例化所有控件之后触发,页面的控件也仅仅是实例化好了,各静态变量也有了初始值,在这个事件里,一般我们可以设置一些事件处理程序等等。
2.              如果是回发那么加载视图状态。
3.              处理回发数据,为控件赋值,这里通过读取回发过来的数据初始化各控件的属性。这样,第一步生成的控件就会有值了。
4.              激发Load事件
5.              处理比如OnChange这样的事件,也就是控件属性和ViewState中的值不同的话,将会激发事件处理程序。
6.              处理页面里的按钮等回发事件。
7.              页面即将展现给用户,也就是即将生成HTML代码前激发的事件,注意这个地方是我们的Ajax关键事件,在这里页面前的初始化和相关事件都处理完了,服务器控件已经具有该有的值了,而Ajax应用只会返回给客户段一小部分HTML或字符串,作为客户端调用AjaxPostBack的返回值,显然此处不下手还等待何时呢,在这里,筛选出我们想要返回给客户端的对象并且只呈现这些对象即可,而执行完这些对象的Render方法之后即可停止Response数据了。
8.              保存视图状态,在aspx中视图状态保存在客户端HTML的隐藏字段__VIEWSTATE中。
9.              依次执行各个控件的Render方法,输出需要呈现的HTML标签,Render方法是asp.net中很关键的方法,每个服务器控件都有相应的Render方法,它的目的就是把自己生成HTML格式的字符串,此字符串最终返回给客户端的浏览器。
10.           最后一步触发卸载页面事件,我们可以在此处理资源回收等操作。
了解了此原理后,我想要理解Ajax的运行原理应该不是大问题了,让我们再了解一下Ajax都有哪些操作,我想不外乎两种方式,一种是不返回值或返回简单字符串形式,客户端通过这点标识操作一些功能,另外一种方式是返回HTML格式内容,比如在网页里的某个区块的动态加载内容,这两种方式大同小意,我们的Ajax在后台都是相似的处理,我想要说明处理过程还是结合示例来说比较通俗,现在就拿在CS2中经常用到的AjaxPager这个控件来说,这个控件在CS2中算是比较高级一点的应用了,与我们的第三方Ajax控件比较类似,使用方法既是在AjaxPager控件里嵌入相应的服务器控件(比如Repeater控件)以后就可以使里面的内容无刷新分页显示数据了,表面上看来是很高深很酷的功能,其实处理过程并不是想象中的那般复杂。
 
![]() <CS:AjaxPager runat="Server" id="PostsPager" ShowFirstLastLinks="false">
<CS:AjaxPager runat="Server" id="PostsPager" ShowFirstLastLinks="false">
![]()
![]() <asp:Repeater id="Posts" runat="Server" >
                                                        <asp:Repeater id="Posts" runat="Server" >
![]()
![]() <ItemTemplate>
                                                               <ItemTemplate>
![]()
![]() <div class="CommonSidebarContentItem">
                                                                      <div class="CommonSidebarContentItem">
![]()
![]() <asp:HyperLink Runat="server" id="TitleLink" />
                                                                             <asp:HyperLink Runat="server" id="TitleLink" />
![]()
![]() </div>
                                                                      </div>
![]()
![]() </ItemTemplate>
                                                               </ItemTemplate>
![]()
![]() </asp:Repeater>
                                                        </asp:Repeater>
![]()
![]() </CS:AjaxPager>
                                                 </CS:AjaxPager>大致分析一下此控件的工作流程:此控件为分页控件,在页面加载的时候赋上分页属性,计算页数,并生成相应的Ajax分页连接,当用户点击分页连接的时候,页面在后台进行ajax提交,通过服务器处理后返回HTML形式的提交结果,并通过js脚本呈现到浏览器上。
![]()
![]() AjaxPager
AjaxPager
![]() public class AjaxPager : Label, IPagedControl
    public class AjaxPager : Label, IPagedControl
![]()
![]() 
    ![]() {
{
![]()
![]()
![]() Member variables and constructor#region Member variables and constructor
        Member variables and constructor#region Member variables and constructor
![]() protected CSContext csContext = CSContext.Current;
        protected CSContext csContext = CSContext.Current;
![]() HyperLink previousLink;
        HyperLink previousLink;
![]() HyperLink nextLink;
        HyperLink nextLink;
![]() HyperLink firstLink;
        HyperLink firstLink;
![]() HyperLink lastLink;
        HyperLink lastLink;
![]() HyperLink[] pagingHyperLinks;
        HyperLink[] pagingHyperLinks;
![]()
![]() protected override void OnPreRender(EventArgs e)
        protected override void OnPreRender(EventArgs e)
![]()
![]() 
        ![]() {
{
![]() base.OnPreRender (e);
            base.OnPreRender (e);
![]()
![]() // Add Page buttons
            // Add Page buttons
![]() //
            //
![]() AddPageLinks();
            AddPageLinks();
![]()
![]() // Add Previous Next child controls
            // Add Previous Next child controls
![]() //
            //
![]() AddPreviousNextLinks();
            AddPreviousNextLinks();
![]()
![]() // Add First Last child controls
            // Add First Last child controls
![]() //
            //
![]() AddFirstLastLinks();
            AddFirstLastLinks();
![]()
![]() }
        }
![]() #endregion
        #endregion
![]()
![]()
![]() Render functions#region Render functions
        Render functions#region Render functions
![]() protected override void Render(HtmlTextWriter writer)
        protected override void Render(HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]() Render(writer, true);
            Render(writer, true);
![]() }
        }
![]()
![]() protected virtual void Render(HtmlTextWriter writer, bool renderContainer)
        protected virtual void Render(HtmlTextWriter writer, bool renderContainer)        
![]()
![]() 
        ![]() {
{
![]() if (renderContainer)
            if (renderContainer)
![]() writer.Write("<div id=\"" + this.ClientID + "_Content\">");
                writer.Write("<div id=\"" + this.ClientID + "_Content\">");
![]()
![]() this.RenderChildren(writer);
            this.RenderChildren(writer);
![]()
![]() if (Visible)
            if (Visible)
![]()
![]() 
            ![]() {
{
![]() int totalPages = CalculateTotalPages();
                int totalPages = CalculateTotalPages();
![]()
![]() // Do we have data?
                // Do we have data?
![]() //
                //
![]() if (totalPages <= 1)
                if (totalPages <= 1)
![]() return;
                    return;
![]()
![]() AddAttributesToRender(writer);
                AddAttributesToRender(writer);
![]()
![]()
![]() // Render the paging buttons
                // Render the paging buttons
![]() //
                //
![]() writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass, false);
                writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass, false);
![]() //writer.RenderBeginTag(HtmlTextWriterTag.Span);
                //writer.RenderBeginTag(HtmlTextWriterTag.Span);
![]()
![]() // Render the first button
                // Render the first button
![]() //
                //
![]() if (this.ShowFirstLastLinks)
                if (this.ShowFirstLastLinks)
![]() RenderFirst(writer);
                    RenderFirst(writer);
![]()
![]() // Render the previous button
                // Render the previous button
![]() //
                //
![]() RenderPrevious(writer);
                RenderPrevious(writer);
![]() 
            
![]() // Render the page button(s)
                // Render the page button(s)
![]() //
                //
![]() RenderPagingButtons(writer);
                RenderPagingButtons(writer);
![]()
![]() // Render the next button
                // Render the next button
![]() //
                //
![]() RenderNext(writer);
                RenderNext(writer);
![]()
![]() // Render the last button
                // Render the last button
![]() //
                //
![]() if (this.ShowFirstLastLinks)
                if (this.ShowFirstLastLinks)
![]() RenderLast(writer);
                    RenderLast(writer);
![]()
![]() //writer.RenderEndTag();
                //writer.RenderEndTag();
![]() }
            }
![]()
![]() if (renderContainer)
            if (renderContainer)
![]() writer.Write("</div>");
                writer.Write("</div>");
![]() }
        }
![]()
![]() void RenderFirst (HtmlTextWriter writer)
        void RenderFirst (HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]()
![]() int totalPages = CalculateTotalPages();
            int totalPages = CalculateTotalPages();
![]()
![]() if ((PageIndex >= 3) && (totalPages > 5))
            if ((PageIndex >= 3) && (totalPages > 5)) 
![]()
![]() 
            ![]() {
{
![]() firstLink.RenderControl(writer);
                firstLink.RenderControl(writer);
![]()
![]() LiteralControl l = new LiteralControl(" 
                LiteralControl l = new LiteralControl(" ![]()  ");
 ");
![]() l.RenderControl(writer);
                l.RenderControl(writer);
![]() }
            }
![]() }
        }
![]()
![]() void RenderLast (HtmlTextWriter writer)
        void RenderLast (HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]() int totalPages = CalculateTotalPages();
            int totalPages = CalculateTotalPages();
![]()
![]() if (((PageIndex + 3) < totalPages) && (totalPages > 5))
            if (((PageIndex + 3) < totalPages) && (totalPages > 5)) 
![]()
![]() 
            ![]() {
{
![]() LiteralControl l = new LiteralControl(" 
                LiteralControl l = new LiteralControl(" ![]()  ");
 ");
![]() l.RenderControl(writer);
                l.RenderControl(writer);
![]()
![]() lastLink.RenderControl(writer);
                lastLink.RenderControl(writer);
![]() }
            }
![]()
![]() }
        }
![]()
![]() void RenderPrevious (HtmlTextWriter writer)
        void RenderPrevious (HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]() Literal l;
            Literal l;
![]()
![]() if (HasPrevious)
            if (HasPrevious) 
![]()
![]() 
            ![]() {
{
![]() previousLink.RenderControl(writer);
                previousLink.RenderControl(writer);
![]()
![]() l = new Literal();
                l = new Literal();
![]() l.Text = " ";
                l.Text = " ";
![]() l.RenderControl(writer);
                l.RenderControl(writer);
![]() }
            }
![]()
![]() }
        }
![]()
![]() void RenderNext(HtmlTextWriter writer)
        void RenderNext(HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]() Literal l;
            Literal l;
![]()
![]() if (HasNext)
            if (HasNext) 
![]()
![]() 
            ![]() {
{
![]()
![]() l = new Literal();
                l = new Literal();
![]() l.Text = " ";
                l.Text = " ";
![]() l.RenderControl(writer);
                l.RenderControl(writer);
![]()
![]() nextLink.RenderControl(writer);
                nextLink.RenderControl(writer);
![]() }
            }
![]()
![]() }
        }
![]()
![]() void RenderButtonRange(int start, int end, HtmlTextWriter writer)
        void RenderButtonRange(int start, int end, HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]()
![]() for (int i = start; i < end; i++)
            for (int i = start; i < end; i++) 
![]()
![]() 
            ![]() {
{
![]()
![]() // Are we working with the selected index?
                // Are we working with the selected index?
![]() //
                //
![]() if (PageIndex == i)
                if (PageIndex == i) 
![]()
![]() 
                ![]() {
{
![]()
![]() // Render different output
                    // Render different output
![]() //
                    //
![]() Literal l = new Literal();
                    Literal l = new Literal();
![]() //l.Text = "<span class=\"currentPage\">[" + (i + 1).ToString() + "]</span>";
                    //l.Text = "<span class=\"currentPage\">[" + (i + 1).ToString() + "]</span>";
![]() l.Text = (i + 1).ToString();
                    l.Text = (i + 1).ToString();
![]()
![]() l.RenderControl(writer);
                    l.RenderControl(writer);
![]() }
                } 
![]() else
                else 
![]()
![]() 
                ![]() {
{
![]() pagingHyperLinks[i].RenderControl(writer);
                    pagingHyperLinks[i].RenderControl(writer);
![]() }
                }
![]() if ( i < (end - 1) )
                if ( i < (end - 1) )
![]() writer.Write(" ");
                    writer.Write(" ");
![]()
![]() }
            }
![]()
![]() }
        }
![]()
![]() void RenderPagingButtons(HtmlTextWriter writer)
        void RenderPagingButtons(HtmlTextWriter writer) 
![]()
![]() 
        ![]() {
{
![]() int totalPages;
            int totalPages;
![]()
![]() // Get the total pages available
            // Get the total pages available
![]() //
            //
![]() totalPages = CalculateTotalPages();
            totalPages = CalculateTotalPages();
![]()
![]() // If we have <= 5 pages display all the pages and exit
            // If we have <= 5 pages display all the pages and exit
![]() //
            //
![]() if ( totalPages <= 5)
            if ( totalPages <= 5) 
![]()
![]() 
            ![]() {
{
![]() RenderButtonRange(0, totalPages, writer);
                RenderButtonRange(0, totalPages, writer);
![]() }
            } 
![]() else
            else 
![]()
![]() 
            ![]() {
{
![]()
![]() int lowerBound = (PageIndex - 2);
                int lowerBound = (PageIndex - 2);
![]() int upperBound = (PageIndex + 3);
                int upperBound = (PageIndex + 3);
![]()
![]() if (lowerBound <= 0)
                if (lowerBound <= 0) 
![]() lowerBound = 0;
                    lowerBound = 0;
![]()
![]() if (PageIndex == 0)
                if (PageIndex == 0)
![]() RenderButtonRange(0, 5, writer);
                    RenderButtonRange(0, 5, writer);
![]()
![]() else if (PageIndex == 1)
                else if (PageIndex == 1)
![]() RenderButtonRange(0, (PageIndex + 4), writer);
                    RenderButtonRange(0, (PageIndex + 4), writer);
![]()
![]() else if (PageIndex < (totalPages - 2))
                else if (PageIndex < (totalPages - 2))
![]() RenderButtonRange(lowerBound, (PageIndex + 3), writer);
                    RenderButtonRange(lowerBound, (PageIndex + 3), writer);
![]()
![]() else if (PageIndex == (totalPages - 2))
                else if (PageIndex == (totalPages - 2))
![]() RenderButtonRange((totalPages - 5), (PageIndex + 2), writer);
                    RenderButtonRange((totalPages - 5), (PageIndex + 2), writer);
![]()
![]() else if (PageIndex == (totalPages - 1))
                else if (PageIndex == (totalPages - 1))
![]() RenderButtonRange((totalPages - 5), (PageIndex + 1), writer);
                    RenderButtonRange((totalPages - 5), (PageIndex + 1), writer);
![]() }
            }
![]() }
        }
![]() #endregion
        #endregion
![]()
![]()
![]() ControlTree functions#region ControlTree functions
        ControlTree functions#region ControlTree functions
![]() void AddPageLinks()
        void AddPageLinks() 
![]()
![]() 
        ![]() {
{
![]() // First add the lower page buttons
            // First add the lower page buttons
![]() //
            //
![]() pagingHyperLinks = new HyperLink[CalculateTotalPages()];
            pagingHyperLinks = new HyperLink[CalculateTotalPages()];
![]()
![]() // Create the buttons and add them to
            // Create the buttons and add them to 
![]() // the Controls collection
            // the Controls collection
![]() //
            //
![]() for (int i = 0; i < pagingHyperLinks.Length; i++)
            for (int i = 0; i < pagingHyperLinks.Length; i++) 
![]()
![]() 
            ![]() {
{
![]() pagingHyperLinks[i] = new HyperLink();
                pagingHyperLinks[i] = new HyperLink();
![]() pagingHyperLinks[i].EnableViewState = false;
                pagingHyperLinks[i].EnableViewState = false;
![]() pagingHyperLinks[i].Text = (i + 1).ToString();
                pagingHyperLinks[i].Text = (i + 1).ToString();
![]() pagingHyperLinks[i].ID = (i + 1).ToString();
                pagingHyperLinks[i].ID = (i + 1).ToString();
![]() pagingHyperLinks[i].NavigateUrl = "#";
                pagingHyperLinks[i].NavigateUrl = "#";
![]() pagingHyperLinks[i].Attributes.Add("onclick", CreatePagerJavaScript((i + 1).ToString()));
                pagingHyperLinks[i].Attributes.Add("onclick", CreatePagerJavaScript((i + 1).ToString()));
![]() }
            }
![]() }
        }
![]()
![]() void AddFirstLastLinks()
        void AddFirstLastLinks() 
![]()
![]() 
        ![]() {
{
![]() int start = 1;
            int start = 1;
![]() firstLink = new HyperLink();
            firstLink = new HyperLink();
![]() firstLink.ID = "First";
            firstLink.ID = "First";
![]() firstLink.Text = ResourceManager.GetString("Utility_Pager_firstButton");
            firstLink.Text = ResourceManager.GetString("Utility_Pager_firstButton");
![]() firstLink.NavigateUrl = "#";
            firstLink.NavigateUrl = "#";
![]() firstLink.Attributes.Add("onclick", CreatePagerJavaScript(start.ToString()));
            firstLink.Attributes.Add("onclick", CreatePagerJavaScript(start.ToString()));
![]()
![]() int last = CalculateTotalPages();
            int last = CalculateTotalPages();
![]() lastLink = new HyperLink();
            lastLink = new HyperLink();
![]() lastLink.ID = "Last";
            lastLink.ID = "Last";
![]() lastLink.Text = ResourceManager.GetString("Utility_Pager_lastButton");
            lastLink.Text = ResourceManager.GetString("Utility_Pager_lastButton");
![]() lastLink.NavigateUrl = "#";
            lastLink.NavigateUrl = "#";
![]() lastLink.Attributes.Add("onclick", CreatePagerJavaScript(last.ToString()));
            lastLink.Attributes.Add("onclick", CreatePagerJavaScript(last.ToString()));
![]() }
        }
![]()
![]() void AddPreviousNextLinks()
        void AddPreviousNextLinks() 
![]()
![]() 
        ![]() {
{
![]() int previous;
            int previous;
![]() 
            
![]() if (this.PageIndex < 2)
            if (this.PageIndex < 2)
![]() previous = 1;
                previous = 1;
![]() else
            else
![]() previous = this.PageIndex;
                previous = this.PageIndex;
![]()
![]() previousLink = new HyperLink();
            previousLink = new HyperLink();
![]() previousLink.ID = "Prev";
            previousLink.ID = "Prev";
![]() previousLink.Text = ResourceManager.GetString("Utility_Pager_previousButton");
            previousLink.Text = ResourceManager.GetString("Utility_Pager_previousButton");
![]() previousLink.NavigateUrl = "#";
            previousLink.NavigateUrl = "#";
![]() previousLink.Attributes.Add("onclick", CreatePagerJavaScript(previous.ToString()));
            previousLink.Attributes.Add("onclick", CreatePagerJavaScript(previous.ToString()));
![]()
![]() int next = this.PageIndex + 2;
            int next = this.PageIndex + 2;
![]() nextLink = new HyperLink();
            nextLink = new HyperLink();
![]() nextLink.ID = "Next";
            nextLink.ID = "Next";
![]() nextLink.Text = ResourceManager.GetString("Utility_Pager_nextButton");
            nextLink.Text = ResourceManager.GetString("Utility_Pager_nextButton");
![]() nextLink.NavigateUrl = "#";
            nextLink.NavigateUrl = "#";
![]() nextLink.Attributes.Add("onclick", CreatePagerJavaScript(next.ToString()));
            nextLink.Attributes.Add("onclick", CreatePagerJavaScript(next.ToString()));
![]() }
        }
![]() #endregion
        #endregion
![]()
![]()
![]() Private Properties#region Private Properties
        Private Properties#region Private Properties
![]() private bool HasPrevious
        private bool HasPrevious 
![]()
![]() 
        ![]() {
{
![]() get
            get 
![]()
![]() 
            ![]() {
{
![]() if (PageIndex > 0)
                if (PageIndex > 0)
![]() return true;
                    return true;
![]()
![]() return false;
                return false;
![]() }
            }
![]() }
        }
![]()
![]() private bool HasNext
        private bool HasNext 
![]()
![]() 
        ![]() {
{
![]() get
            get 
![]()
![]() 
            ![]() {
{
![]() if (PageIndex + 1 < CalculateTotalPages() )
                if (PageIndex + 1 < CalculateTotalPages() )
![]() return true;
                    return true;
![]()
![]() return false;
                return false;
![]() }
            }
![]() }
        }
![]() #endregion
        #endregion
![]()
![]()
![]() Helper methods and Public Properties#region Helper methods and Public Properties
        Helper methods and Public Properties#region Helper methods and Public Properties
![]()
![]() string url = "AjaxPager.GetPage('{0}', {1}, new Function('result', 'if (result.error) {{ alert(result.error); }} else {{ document.getElementById(\\'{0}_Content\\').innerHTML = result.value; }}')); return false;";
        string url = "AjaxPager.GetPage('{0}', {1}, new Function('result', 'if (result.error) {{ alert(result.error); }} else {{ document.getElementById(\\'{0}_Content\\').innerHTML = result.value; }}')); return false;";
![]() protected virtual string CreatePagerJavaScript(string pageIndex)
        protected virtual string CreatePagerJavaScript(string pageIndex)
![]()
![]() 
        ![]() {
{
![]() return string.Format(url, this.ClientID, pageIndex);
            return string.Format(url, this.ClientID, pageIndex);
![]() }
        }
![]()
![]() // *********************************************************************
        // *********************************************************************
![]() //  CalculateTotalPages
        //  CalculateTotalPages
![]() //
        //
![]()
![]() /**//// <summary>
        /**//// <summary>
![]() /// Static that caculates the total pages available.
        /// Static that caculates the total pages available.
![]() /// </summary>
        /// </summary>
![]() ///
        /// 
![]() // ********************************************************************/
        // ********************************************************************/
![]() public virtual int CalculateTotalPages()
        public virtual int CalculateTotalPages() 
![]()
![]() 
        ![]() {
{
![]() int totalPagesAvailable;
            int totalPagesAvailable;
![]()
![]() if (TotalRecords == 0)
            if (TotalRecords == 0)
![]() return 0;
                return 0;
![]()
![]() // First calculate the division
            // First calculate the division
![]() //
            //
![]() totalPagesAvailable = TotalRecords / PageSize;
            totalPagesAvailable = TotalRecords / PageSize;
![]()
![]() // Now do a mod for any remainder
            // Now do a mod for any remainder
![]() //
            //
![]() if ((TotalRecords % PageSize) > 0)
            if ((TotalRecords % PageSize) > 0)
![]() totalPagesAvailable++;
                totalPagesAvailable++;
![]()
![]() return totalPagesAvailable;
            return totalPagesAvailable;
![]() }
        }
![]() 
        
![]() int _pageIndex = 0;
        int _pageIndex = 0;
![]() public virtual int PageIndex
        public virtual int PageIndex 
![]()
![]() 
        ![]() {
{
![]() get
            get 
![]()
![]() 
            ![]() {
{
![]() // Give first try to the ViewState if it was a postback
                // Give first try to the ViewState if it was a postback
![]() if (Page.IsPostBack && ViewState["PageIndex"] != null)
                if (Page.IsPostBack && ViewState["PageIndex"] != null)
![]()
![]() 
                ![]() {
{
![]() _pageIndex = (int) ViewState["PageIndex"];
                    _pageIndex = (int) ViewState["PageIndex"];
![]() }
                }
![]() else
                else 
![]()
![]() 
                ![]() {
{
![]() if (csContext.QueryString["pageindex"] != null)
                    if (csContext.QueryString["pageindex"] != null)
![]() _pageIndex = int.Parse(csContext.QueryString["pageindex"]) - 1;
                        _pageIndex = int.Parse(csContext.QueryString["pageindex"]) - 1;
![]() }
                }
![]()
![]() if (_pageIndex < 0)
                if (_pageIndex < 0)
![]() return 0;
                    return 0;
![]() else
                else
![]() return _pageIndex;
                    return _pageIndex;
![]() }
            }
![]() set
            set 
![]()
![]() 
            ![]() {
{
![]() ViewState["PageIndex"] = value;
                ViewState["PageIndex"] = value;
![]() _pageIndex = value;
                _pageIndex = value;
![]() }
            }
![]() }
        }
![]()
![]() public virtual int PageSize
        public virtual int PageSize 
![]()
![]() 
        ![]() {
{
![]() get
            get 
![]()
![]() 
            ![]() {
{
![]() int pageSize = Convert.ToInt32(ViewState["PageSize"]);
                int pageSize = Convert.ToInt32(ViewState["PageSize"]);
![]()
![]() if (pageSize == 0)
                if (pageSize == 0) 
![]() return 10;
                    return 10;
![]()
![]() return pageSize;
                return pageSize;
![]() }
            }
![]() set
            set 
![]()
![]() 
            ![]() {
{
![]() ViewState["PageSize"] = value;
                ViewState["PageSize"] = value;
![]() }
            }
![]()
![]() }
        }
![]()
![]() public virtual bool ShowFirstLastLinks
        public virtual bool ShowFirstLastLinks
![]()
![]() 
        ![]() {
{
![]() get
            get
![]()
![]() 
            ![]() {
{
![]() object state = ViewState["ShowFirstLastLinks"];
                object state = ViewState["ShowFirstLastLinks"];
![]() if (state == null)
                if (state == null)
![]() return true;
                    return true;
![]() else
                else
![]() return (bool) state;
                    return (bool) state;
![]() }
            }
![]() set
            set
![]()
![]() 
            ![]() {
{
![]() ViewState["ShowFirstLastLinks"] = value;
                ViewState["ShowFirstLastLinks"] = value;
![]() }
            }
![]() }
        }
![]()
![]() private bool _causeValidation = true;
        private bool _causeValidation = true;
![]() public bool CausesValidation
        public bool CausesValidation
![]()
![]() 
        ![]() {
{
![]()
![]() get
            get ![]() {return _causeValidation;}
{return _causeValidation;}
![]()
![]() set
            set ![]() {_causeValidation = value;}
{_causeValidation = value;}
![]() }
        }
![]()
![]() public int TotalRecords
        public int TotalRecords 
![]()
![]() 
        ![]() {
{
![]() get
            get 
![]()
![]() 
            ![]() {
{
![]() return Convert.ToInt32(ViewState["TotalRecords"]);
                return Convert.ToInt32(ViewState["TotalRecords"]);
![]() }
            }
![]() set
            set 
![]()
![]() 
            ![]() {
{
![]() ViewState["TotalRecords"] = value;
                ViewState["TotalRecords"] = value;
![]() }
            }
![]() }
        }
![]()
![]() /**//// <summary>
        /**//// <summary>
![]() /// Making sure to strip the existing pager value from the querystring before appending a new one
        /// Making sure to strip the existing pager value from the querystring before appending a new one
![]() /// </summary>
        /// </summary>
![]() /// <param name="RawURL">Usually CSContext.Current.RawUrl</param>
        /// <param name="RawURL">Usually CSContext.Current.RawUrl</param>
![]() /// <param name="QueryName">Usually "pageindex"</param>
        /// <param name="QueryName">Usually "pageindex"</param>
![]() /// <returns></returns>
        /// <returns></returns>
![]() public string UrlCleaner(string RawURL, string QueryName)
        public string UrlCleaner(string RawURL, string QueryName)
![]()
![]() 
        ![]() {
{
![]() // Configure the Url
            // Configure the Url
![]() if(RawURL.IndexOf("?") != -1)
            if(RawURL.IndexOf("?") != -1)
![]()
![]() 
            ![]() {
{
![]() bool hasPart = false;
                bool hasPart = false;
![]() string queryString = RawURL.Substring( RawURL.IndexOf("?") + 1 );
                string queryString = RawURL.Substring( RawURL.IndexOf("?") + 1 );
![]() string[] parts = queryString.Split('&');
                string[] parts = queryString.Split('&');
![]() for(int i = 0 ; i < parts.Length ; i++)
                for(int i = 0 ; i < parts.Length ; i++)
![]()
![]() 
                ![]() {
{
![]() if(parts[i].StartsWith(QueryName))
                    if(parts[i].StartsWith(QueryName))
![]()
![]() 
                    ![]() {
{
![]() parts[i] = QueryName + "={0}";
                        parts[i] = QueryName + "={0}";
![]() hasPart = true;
                        hasPart = true;
![]() }
                    }
![]() }
                }
![]() if(hasPart == true)
                if(hasPart == true)
![]() RawURL = RawURL.Replace(queryString, string.Join("&", parts));
                    RawURL = RawURL.Replace(queryString, string.Join("&", parts));
![]() else
                else
![]() RawURL = RawURL.Replace(queryString, string.Join("&", parts) + "&" + QueryName + "={0}");
                    RawURL = RawURL.Replace(queryString, string.Join("&", parts) + "&" + QueryName + "={0}");
![]() }
            }
![]() else
            else
![]() RawURL = RawURL + "?" + QueryName + "={0}";
                RawURL = RawURL + "?" + QueryName + "={0}";
![]()
![]() return RawURL;
            return RawURL;
![]()
![]() }
        }
![]()
![]() #endregion
        #endregion
![]()
![]() public override bool Visible
        public override bool Visible
![]()
![]() 
        ![]() {
{
![]() get
            get
![]()
![]() 
            ![]() {
{
![]() object state = this.ViewState["Visible"];
                object state = this.ViewState["Visible"];
![]() if (state == null)
                if (state == null)
![]() return true;
                    return true;
![]() else
                else
![]() return (bool) state;
                    return (bool) state;
![]() }
            }
![]() set
            set
![]()
![]() 
            ![]() {
{
![]() this.ViewState["Visible"] = value;
                this.ViewState["Visible"] = value;
![]() }
            }
![]() }
        }
![]()
![]()
![]() AJAX#region AJAX
        AJAX#region AJAX
![]()
![]() protected override void OnInit(EventArgs e)
        protected override void OnInit(EventArgs e)
![]()
![]() 
        ![]() {
{
![]() base.OnInit (e);
            base.OnInit (e);
![]() AjaxManager.Register(this, "AjaxPager");
            AjaxManager.Register(this, "AjaxPager");
![]() }
        }
![]() 
        
![]() [AjaxMethod(IncludeControlValuesWithCallBack=true)]
        [AjaxMethod(IncludeControlValuesWithCallBack=true)]
![]() public virtual string GetPage(int page)
        public virtual string GetPage(int page)
![]()
![]() 
        ![]() {
{
![]() StringWriter stringWriter = new StringWriter();
            StringWriter stringWriter = new StringWriter();
![]() HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
![]()
![]() AddPageLinks();
            AddPageLinks();
![]() AddPreviousNextLinks();
            AddPreviousNextLinks();
![]()
![]() if (this.ShowFirstLastLinks)
            if (this.ShowFirstLastLinks)
![]() AddFirstLastLinks();
                AddFirstLastLinks();
![]()
![]() this.Render(htmlWriter, false);
            this.Render(htmlWriter, false);
![]()
![]() return stringWriter.ToString();
            return stringWriter.ToString();
![]() }
        }
![]()
![]() #endregion
        #endregion
![]() }
    }关键一点是让程序注册PreRender处理事件,我们知道,在此事件控件还没有生成HTML代码,也就是Response对象里还没有具体的HTML代码,所有的控件还没有执行Reader方法,这里我们就可以选择想执行Reader方法的控件而忽略其他控件,在此我们只需要执行包含在AjaxPager控件内的控件(也就是AjaxPager的子控件)的Reader方法, 这样就可以保证Response给客户端的是纯净的,只在AjaxPager控件内部的控件的HTML实现。
让我看看此控件重写的OnInit方法,此方法里的AjaxManager.Register(this, "AjaxPager");这一句在前面一章已经介绍过,为注册Ajax的回发脚本,当然它还有另外一个作用那就是注册PreRender事件,当触发PreReader事件 到时候,AjaxManager会去找控件里具有AjaxMethod属性的方法来执行,让我们看看在AjaxPager里的AjaxMethod都干了些什么:
 
![]() [AjaxMethod(IncludeControlValuesWithCallBack=true)]
[AjaxMethod(IncludeControlValuesWithCallBack=true)]
![]()
![]() public virtual string GetPage(int page)
         public virtual string GetPage(int page)
![]()
![]()
![]() 
         ![]() {
{
![]()
![]() StringWriter stringWriter = new StringWriter();
              StringWriter stringWriter = new StringWriter();
![]()
![]() HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
              HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
![]()
![]() 
 
![]()
![]() AddPageLinks();
              AddPageLinks();
![]()
![]() AddPreviousNextLinks();
              AddPreviousNextLinks();
![]()
![]() 
 
![]()
![]() if (this.ShowFirstLastLinks)
              if (this.ShowFirstLastLinks)
![]()
![]() AddFirstLastLinks();
                   AddFirstLastLinks();
![]()
![]() 
 
![]()
![]() this.Render(htmlWriter, false);
              this.Render(htmlWriter, false);
![]()
![]() 
 
![]()
![]() return stringWriter.ToString();
              return stringWriter.ToString();
![]()
![]() }
          }
![]()
![]()
可以看出,倒数第二句就是Reader方法,输出的HTML保存到HtmlTextWriter中,最后一句即是把控件的HTML呈现字符串对象返回给调用者(这里指的是AjaxManager),AjaxManager获得值后按照指定的格式Response到客户端,并中止其他的Response,客户端通过调用document.getElementById(‘’).innerHTML = result.value来向浏览器呈现指定区域的数据。