客户端翻页 程序

导言:datagrid 作为asp.net 商务产品的一部分,为开发人员提过了许多更简便的开发方法,但是datagrid 就像是一个拐杖,虽然他可以帮助你行走,同时他也限制你不能跑。很多时候,项目或者用户的要求使得datagrid 显得很臃肿和受限制。就是这样一个项目,为了满足我的所有客户的需要,我不得不临时不使用这种拖拽式的开发方法。

背景:我最近面临的是一个大多是公司都会使用的项目,它要求显示一个数量还算比较大的买卖计划数据集。最基本的内容是,用户需要看到一个能够通过按钮控制上下翻页的计划列表。上下翻页按钮可以使窗体在内部更换上下页的数据内容。而且客户需要页面回发保持到最小次数,就是这个要求,让我不得不改变我的原来的想法---通过一个基于回发选择不同选项的dropdownlist 来改变分页的想法。

我后来通过扩展 code project 上面的一篇Al Alberto’s Master Detail DDL project文章来解决我的问题,。但是这个分页仍然存在一些问题,我试了很多种关于Datagrid 和Repeaters 的技术,但是他们都太复杂了,比我认为实际需要的代码多出好几百行,这些方法中比较优秀的方法是Andrew Merlino’s article and code.

最后,我意识到html 中的table 可以向div层一样工作。通过设定table的style=”display:none”属性,我可以在客户端隐藏这个table。我所要做的就是为每一个页都创建这样一个table. 这些table 包含只有一列的标题行,还有存放内容的独立单元格。还有一组连续的存放格化后数据的table,在内容单元格中我可以放置任何东西(比如我的demo)。所有的这些都通过动态的创建一个javascript来处理客户端的翻页请求

 

使用代码:在我的例子中,内功是很简单的,包含了一个单独的有code-behind的aspx, code-behind 的代码少于250 行,下面是解决方案的简单步骤

获得一个包含一个datatble的dataset
根据记录集的行数和用户定义的每页看到的行数 来计算页数,
为每一个页创建一个容器table
为每一行数建创建一个子table
将子表添加到容器table
添加这个容器table到页面,并设置runat=”server”.
将javascript 添加到页面
在这个例子中我使用了sql server 中的Northwind 数据库,你可以通过更改连接字符串设置成你自己定义的数据库

 

private void BuildTables ()

{

    NumItems =  ds.Tables[0].Rows.Count;

    PageSize =  Int32.Parse(txtPageSize.Text);

 

    //Determine number of pages minus any leftover records long

    Pages = (NumItems / PageSize);

 

    //Save this number for future reference long

    WholePages = NumItems / PageSize;

 

    //Determine number of leftover records int

    Leftover = NumItems % PageSize;

 

    //If there are leftover records, increase page count by one

    if(Leftover > 0)

    {

        Pages += 1;

    }

    this.BuildJSFunctions(Convert.ToInt32(Pages));

    int StartOfPage = 0;

 

    int EndOfPage = PageSize;

 

    this.lblPages.Text = Pages.ToString() + " Pages";

 

    this.lblRecords.Text = NumItems.ToString() + " Records";

 

    for(int p= 1;p<=Pages;p++)

    {

        //Create Page Tables

        HtmlTable tblPage = new HtmlTable();

        HtmlTableRow trow = new HtmlTableRow();

        HtmlTableRow hrow = new HtmlTableRow();

        HtmlTableCell hcell = new HtmlTableCell();

        hcell.InnerHtml = "Page " +p.ToString()+"";

        hrow.Cells.Add(hcell);

        tblPage.Rows.Add(hrow);

        HtmlTableCell tcell = new HtmlTableCell();

        tblPage.ID = "Page"+p;

        if(p==1)

            tblPage.Style.Add("Display","block");

        else

            tblPage.Style.Add("Display","none");

        //Now, I want to get a row formatted as a table.  This

        //is capability is really the whole reason for this project.

 

        for(int i = StartOfPage;i<=EndOfPage;i++)

        {

            //Make sure there is another row in the dataset

            if(i<ds.Tables[0].Rows.Count)

                tcell.Controls.Add(FillPages(i));

        }

        trow.Cells.Add(tcell);

        tblPage.Rows.Add(trow);

        HtmlTableCell tdPages = (HtmlTableCell)FindControl("tdPages");

        tdPages.Controls.Add(tblPage);

 

        //set the page numbers

        StartOfPage = EndOfPage+1;

        EndOfPage = EndOfPage+PageSize;

    }

}

 

上面的方法循环调用FillPages (int Record)方法,为当前的行返回一个接收的table ,。另外还有更多好的方法可以获得当前的datatable有多少行。 整个项目都很简单

private HtmlTable FillPages(int Record)

{

    HtmlTable tblNew = new HtmlTable();

    HtmlTableRow r1 = new HtmlTableRow();

    HtmlTableRow r2 = new HtmlTableRow();

    HtmlTableCell c1 = new HtmlTableCell();

    HtmlTableCell c2 = new HtmlTableCell();

    HtmlTableCell c3 = new HtmlTableCell();

    //format the cells

    tblNew.Border=1;

    tblNew.CellSpacing=0;

    tblNew.CellPadding=3;

    tblNew.Width = "520px";

    c1.ColSpan = 2;

    c1.BgColor="silver";

    c1.Style.Add("FONT-COLOR","WHITE");

    c2.Width="80%";

    c3.Width = "20%";

    //fill cells

    c1.InnerHtml = "Product ID: " + ds.Tables[0].Rows[Record][0].ToString();

    c2.InnerHtml = ds.Tables[0].Rows[Record][1].ToString();

    c3.InnerHtml = ds.Tables[0].Rows[Record][2].ToString();

    //assign cells to rows

    r1.Cells.Add(c1);

    r2.Cells.Add(c2);

    r2.Cells.Add(c3);

    //assign rows to table

    tblNew.Rows.Add(r1);

    tblNew.Rows.Add(r2);

    return tblNew;

}

BuildTables 调用BuildJSFunctions (int Pages) 方法来获得当前产生的是第几页,然后向这个页添加相应的javascript.这个方法可以针对每个执行情况拆分为四部分,我为了简单所以把他们包含在一个函数里面了,将来可以更具需要来拆分他们。

private void BuildJSFunctions(int Pages)

{

    int MaxPage = Pages+1;

 

    StringBuilder s =

       new StringBuilder("/n<script language=JavaScript>/n");

    //Move to Previous Page

    s.Append("function __onPrevPage ()/n");

    s.Append("{/n");

    s.Append("for (var i=2; i<"+ MaxPage +"; i++) {/n");

    s.Append("if (document.getElementById ('Page' + i).style." +

                                     "display == 'block') {/n");

    s.Append("  document.all('Page' + i).style.display = 'none';/n");

    s.Append("    document.all('Page' + (i - 1)).style.display = 'block';/n");

    s.Append("    break;/n");

    s.Append("}/n");

    s.Append("}/n");

    s.Append("}/n");

    s.Append("/n");

 

    //Move to Next Page

    s.Append("function __onNextPage ()/n");

    s.Append("{/n");

    s.Append("for (var i=1; i<"+ Pages +"; i++) {/n");

    s.Append(" if (document.getElementById ('Page' + i).style" +

                                    ".display == 'block') {/n");

    s.Append("document.all('Page' + i).style.display = 'none';/n");

    s.Append(" document.all('Page' + (i + 1)).style.display = 'block';/n");

    s.Append(" break;/n");

    s.Append(" }/n");

    s.Append(" }/n");

    s.Append(" }/n");

 

    //Jump to First Page

    s.Append("function __onFirstPage ()/n");

    s.Append("{/n");

    s.Append("for (var i=2; i<"+ MaxPage +"; i++) {/n");

    s.Append(" if (document.getElementById ('Page' + i).style" +

                                     ".display == 'block') {/n");

    s.Append("document.all('Page' + i).style.display = 'none';/n");

    s.Append(" document.all('Page' + (1)).style.display = 'block';/n");

    s.Append(" break;/n");

    s.Append(" }/n");

    s.Append(" }/n");

    s.Append(" }/n");

 

    //Jump to Last Page

    s.Append("function __onLastPage ()/n");

    s.Append("{/n");

    s.Append("for (var i=1; i<"+ MaxPage +"; i++) {/n");

    s.Append(" if (document.getElementById ('Page' + i).style." +

                                      "display == 'block') {/n");

    s.Append("document.all('Page' + i).style.display = 'none';/n");

    s.Append(" document.all('Page" + Pages +"').style.display = 'block';/n");

    s.Append(" break;/n");

    s.Append(" }/n");

    s.Append(" }/n");

    s.Append(" }/n");

 

    s.Append("</script>");

    Response.Write(s.ToString());

}

 

 

There are many ways to make this project more robust and re-usable. For future development, I intend to create a ClientPaging class that separates the formatting from the logic. I would also caution against using this approach with very large sets of data. The time required to download many rich tables would be prohibitive. Still, when you consider the time and server resources required for posting back every page change, there is a point at which my approach makes more sense than server-side paging.

 

The only postback that occurs is when the user changes the default Page Size. I’ve set the text box’s AutoPostBack property to true so that users can easily adjust the size. Future considerations might include setting a cookie with the user’s preferred page size.

 

扩展点:有很多方法可以使这个项目变得更完善和可重复利用。为了将来的开发我想创建一个逻辑和表示分离的ClientPaging类,我建议非常大量的数据不要使用这个平台,下载大量的数据到客户端会造成超时的,如果你的程序要求的尽量少的回发操作和快的响应,我的方法会比服务器端翻页更有效率。

唯一的回发发生在,用户更改默认显示的大小时。我已经设置了text的AutoPostBack=true ,这样用户可以轻易改变显示内容的大小。将来可能还会考虑将用户设置的内容保存到cookie中

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yaotiebing/archive/2005/02/03/279300.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值