从这里出发,力争做一位新手中的高手....——lxinxuan's Blog

posts - 170, comments - 427, trackbacks - 26, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理
·摘要
           素材来自于最近完成的一个.net1.0项目。因为DataGrid自带的分页功能不够完善,所以自己写了个控件,用途是支持DataGrid的自定义分页,主要包含首页、上一页、下一页、尾页;任意跳转页;显示所有页数信息等。这个分页控件可以提供给任何需要的DataGrid使用。

·设计思路
            为了让这个控件能够适用于每个页面,定义了一个接口ICurrentIndex,ICurrentIndex中定义了绑定方法BindData(),以及两个属性int CurrentIndex和int PageCount。这样,每个需要使用分页控件的页面,除了本身继承自Page外,还必须实现接口ICurrentIndex,而且实现绑定方法BindData()。当然,如果你的用户控件仅仅给一个DataGrid使用,无须这么麻烦通过接口来实现。

以下就是效果图:


·如何使用
            1)当然把分页控件拉到页面上的DataGrid下面了。DisplayPageNumber属性决定是显示下拉框还是任意输入,本文不做细节讨论。
<TR>
                    <TD><asp:datagrid id="DataGrid1" runat="server" Height="144px" Width="552px" AllowPaging="True" PageSize="5">
                            <PagerStyle Visible="False"></PagerStyle>
                        </asp:datagrid></TD>
                </TR>
                <TR>
                    <TD><uc1:navigation id="navigation" runat="server" DisplayPageNumber="false"></uc1:navigation></TD>
                </TR>

            2)在页面的CodeBehind(2.0中叫CodeFile)里,实现接口ICurrentIndex
public class _Default : System.Web.UI.Page, ICurrentIndex
{……}

            3)实现接口中的BindData方法:public void BindData(),在这个方法中,实现绑定DataGrid之后,把DataGrid的页数PageCount(PageCount=(int)Math.Ceiling( 记录总数recordCount * 1.0 / DataGrid.PageSize);)作为参数,传给用户控件里的方法AddPageCount;同时把PageCount、PageSize、记录总数recordCount,以及DataGird的CurrentPageIndex作为参数传给分页控件的NavigationStateChange()方法。

/// <summary>
  /// BindDataGrid
  /// </summary>
  public void BindData()
  {
   DataTable dt = new DataTable();
   if(Session["datasource"] == null)
   {
    string cmdText = "SELECT top 26 ProductID,ProductName,QuantityPerUnit,UnitPrice FROM Products";
    dt = SQLHelper.FillDataTable(cmdText);

    Session["datasource"] = dt;
   }
   else
   {
    dt = (DataTable)Session["datasource"];
   }
   
   if(dt!= null  && dt.Rows.Count > 0)
   {
    this.recordCount = dt.Rows.Count;
    this.pageCount = (int)Math.Ceiling( this.recordCount * 1.0 / this.DataGrid1.PageSize);
   
    ViewState["RecordCount"] = this.recordCount;
    ViewState["PageCount"] = this.pageCount;

    this.DataGrid1.DataSource = dt.DefaultView;
    this.DataGrid1.DataBind();
   }
   else
   {
    this.DataGrid1.Visible = false;
   }

   this.navigation.AddPageCode(this.pageCount);
   this.navigation.NavigationStateChange(this.pageCount, this.DataGrid1.PageSize, this.recordCount, this.DataGrid1.CurrentPageIndex);
  }


            4)实现接口中的两个属性。
public int CurrentIndex
        
{
            
get
            
{
                
return this.DataGrid1.CurrentPageIndex;
            }

            
set
            
{
                
this.DataGrid1.CurrentPageIndex = value;
            }

        }


        
public int PageCount
        
{
            
get
            
{
                
return this.pageCount;
            }

        }
   
         5)自此,页面部分的代码已经做完,不算复杂吧。下面开始看看用户控件中的代码:
            6)分页控件中的public void AddPageCode(int pageCount):把页码显示在下拉框中。
public void AddPageCode(int pageCount)
        
{
            
if(this.displayPageNumber)//显示下拉框页码
            {
                
this.txtPageNumber.Visible = false;
                
this.btnGo.Visible = false;
                
this.ddlPageIndex.Items.Clear();//先清除
                for(int i=1;i<= pageCount;i++)
                
{
                    
this.ddlPageIndex.Items.Add(i.ToString());
                }

            }

            
else//否则让用户自己输入页码
            {
                
this.txtPageNumber.Visible = true;
                
this.btnGo.Visible = true;
                
this.ddlPageIndex.Visible = false;
            }

        }

            7)分页控件中的public void NavigationStateChange(int pageCount, int pageSize, int recordCount, int currentIndex)方法:根据传入的参数,控制导航按钮或数字的状态。
/// <summary>
        
/// 控制导航按钮或数字的状态
        
/// </summary>
        public void NavigationStateChange(
int pageCount, int pageSize, int recordCount, int currentIndex)
        {
            this
.LtlPageCount.Text = pageCount.ToString();
            this
.LtlPageIndex.Text = "1";
            this
.LtlPageSize.Text = pageSize.ToString();
            this
.LtlRecordCount.Text = recordCount.ToString();

            
if( pageCount <= 1 )//( RecordCount <= PageSize )//小于等于一页
            {
                this
.LBtnFirst.Enabled = false;
                this
.LBtnPrev.Enabled = false;
                this
.LBtnNext.Enabled = false;
                this
.LBtnLast.Enabled = false;
            }
            
else //有多页
            {
                
if( currentIndex == 0 )//当前为第一页
                {
                    this
.LBtnFirst.Enabled = false;
                    this
.LBtnPrev.Enabled = false;
                    this
.LBtnNext.Enabled = true;
                    this
.LBtnNext.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnLast.Enabled = true;
                    this
.LBtnLast.ForeColor = System.Drawing.Color.Red;
                }
                
else if(currentIndex == pageCount - 1 )//当前为最后页 
                {
                    this
.LBtnFirst.Enabled = true;
                    this
.LBtnFirst.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnPrev.Enabled = true;
                    this
.LBtnPrev.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnNext.Enabled = false;
                    this
.LBtnLast.Enabled = false;
                }
                
else //中间页
                {
                    this
.LBtnFirst.Enabled = true;
                    this
.LBtnFirst.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnPrev.Enabled = true;
                    this
.LBtnPrev.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnNext.Enabled = true;
                    this
.LBtnNext.ForeColor = System.Drawing.Color.Red;
                    this
.LBtnLast.Enabled = true;
                    this
.LBtnLast.ForeColor = System.Drawing.Color.Red;
                }                  
            }

            
if(recordCount == 0)//当没有纪录时DataGrid.PageCount会显示1页
                this
.LtlPageCount.Text = "0";
            
else
                this
.LtlPageCount.Text = pageCount.ToString();
            
if(recordCount == 0)
                this
.LtlPageIndex.Text = "0";
            
else
                this
.LtlPageIndex.Text = (currentIndex + 1).ToString();//在有页数的情况下前台显示页数加1
            this
.LtlPageSize.Text = pageSize.ToString();
            this
.LtlRecordCount.Text = recordCount.ToString();

            this
.ddlPageIndex.SelectedIndex = currentIndex;
        }

            8)控件中跳转控制代码:主要是设置DataGrid的CurrentIndex,并调用页面中的BindData()方法。
private void btnGo_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            
if(this.txtPageNumber.Text.Trim() != "")
            {
                
int index = Convert.ToInt32(this.txtPageNumber.Text.Trim()) - 1;
                
if(index < 0)
                {
                    
index = 0;
                }
                
else if(index >= Convert.ToInt32(this.LtlPageCount.Text))
                {
                    
index = Convert.ToInt32(this.LtlPageCount.Text) - 1;
                }
                this
.txtPageNumber.Text = (index + 1).ToString();
                this
.iParent.CurrentIndex = index;
                this
.iParent.BindData();
            }
            
else
            {
                this
.iParent.BindData();
                
return;//this.RegularExpressionValidator1.IsValid = false;
            }
        }

完整代码下载: http://files.cnblogs.com/lxinxuan/DataGridPager.rar

Feedback

#1楼   回复  引用    

2007-04-19 20:45 by 蓝梦[未注册用户]
呵呵,我也发一个分页控件,具体去看截图

http://www.xgamesdev.com/bbs/showtopic-339.aspx

#2楼[楼主]   回复  引用  查看    

2007-04-19 20:55 by ColdDog      
@蓝梦
呵呵,商用~:)
虽然不错,但不是学习之用

#3楼   回复  引用    

2007-04-19 21:47 by 蓝梦[未注册用户]
@ColdDog

呵呵,一种形式而已,我虽然没有公开代码,但没有加入任何不良代码。
大家喜欢可以免费用的了。

#4楼[楼主]   回复  引用  查看    

2007-04-19 21:50 by ColdDog      
@蓝梦
嗯,不错~支持先~~

#5楼   回复  引用  查看    

2007-04-20 01:27 by 木野狐      
我写的一个支持自定义分页的显示。不过是 UserControl.

#6楼[楼主]   回复  引用  查看    

2007-04-20 08:10 by ColdDog      
@木野狐
本文介绍的也是UserControl,比你少一个自定义分页功能~呵呵,03的项目,整理一下,以后可能更加注重编码和架构方面了~

#7楼   回复  引用  查看    

2007-04-20 09:04 by kiler      
public void BindData()
{
DataTable dt = new DataTable();
if(Session["datasource"] == null)
{
string cmdText = "SELECT top 26 ProductID,ProductName,QuantityPerUnit,UnitPrice FROM Products";
dt = SQLHelper.FillDataTable(cmdText);

Session["datasource"] = dt;
}
else
{
dt = (DataTable)Session["datasource"];
}


这样的写法不好,假设10个人在半小时内先后访问过你这个页面,每个人都是查出1000条数据的话,那么你的内存就有1w条数据,而且由于数据是存在session里面的,即时关闭该页面,数据在半个小时之内还是会继续占用内存,访问的人稍稍多一点,你的服务器酒会垮掉。

#8楼   回复  引用    

2007-04-20 09:11 by 呵呵[未注册用户]
蓝梦的是服务器控件。

#9楼[楼主]   回复  引用  查看    

2007-04-20 09:19 by ColdDog      
@kiler
谢谢指正~
我那个应用只是一个单位内部资产查询,没几号用户的~
不过数据倒是蛮多的...呵呵~后来我们通过数据分页查询得到比较理想的效果~

你也说说你的做法吧,学习一下...
目前我还没有接触那些对效率要求特别高的系统,所以倒是忽略了这方面的训练...

#10楼   回复  引用  查看    

2007-04-20 10:09 by kiler      
@ColdDog

我基本上是不用Datagrid的分页功能,因为我觉得Datagrid的分页功能设计很不合理,你必须把所有的数据绑定到Datagrid的Datasource才能实现分页功能。所以我一般会采用分页读取数据的,每一页只读取当页的数据,不把所有的数据读出来。分页条的显示采用第三方的开源控件AspNetPager,datagrid用来显示当页的数据。

<%@Register TagPrefix="Webdiyer" Namespace="Wuqi.Webdiyer" Assembly="aspnetpager"%>
<%@Import Namespace="System.Data.OleDb"%>
<%@ Import Namespace="System.Data"%>
<%@ Page Language="C#" debug=true%>
<HTML>
<HEAD>
<TITLE>Welcome to Webdiyer.com </TITLE>
<script runat="server">
OleDbConnection conn;
OleDbCommand cmd;
void Page_Load(object src,EventArgs e){
conn=new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Server.MapPath("access/aspnetpager.mdb"));
if(!Page.IsPostBack){
cmd=new OleDbCommand("select count(newsid) from wqnews",conn);
conn.Open();
pager.RecordCount=(int)cmd.ExecuteScalar();
conn.Close();
BindData();
}
}

void BindData(){
cmd=new OleDbCommand("select newsid,heading,source,addtime from wqnews order by addtime desc",conn);
OleDbDataAdapter adapter=new OleDbDataAdapter(cmd);
DataSet ds=new DataSet();
adapter.Fill(ds,pager.PageSize*(pager.CurrentPageIndex-1),pager.PageSize,"news");
dg.DataSource=ds.Tables["news"];
dg.DataBind();
}

void ChangePage(object src,PageChangedEventArgs e){
pager.CurrentPageIndex=e.NewPageIndex;
BindData();
}

</script>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="content-type" content="text/html;charset=gb2312">
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="Webdiyer(yhaili@21cn.com)">
</HEAD>
<body>
<form runat="server" ID="Form1">
<h2 align="center">AspNetPager分页示例</h2>
<asp:DataGrid id="dg" runat="server"
Width="760" CellPadding="4" Align="center" />

<Webdiyer:AspNetPager runat="server" id="pager"
OnPageChanged="ChangePage"
HorizontalAlign="center"
style="MARGIN-TOP:10px;FONT-SIZE:16px"
PageSize="8"
ShowInputBox="always"
SubmitButtonStyle="border:1px solid #000066;height:20px;width:30px"
InputBoxStyle="border:1px #0000FF solid;text-align:center"
SubmitButtonText="转到"
UrlPaging="true"
UrlPageIndexName="pageindex" />
</form>
</body>
</HTML>


以上是分页读取数据的例子,你要是有兴趣可以去http://www.0zhe.com/AspNetPager/default.aspx看看">http://www.0zhe.com/AspNetPager/default.aspx看看,那里有更多的例子。

#11楼[楼主]   回复  引用  查看    

2007-04-20 10:30 by ColdDog      
嗯~不错
我也是采用分页读取数据的方法,再结合我提供的分页控件,也可以达到满意的效果~
如今几乎不用03做项目了,05中的GridView似乎还凑合着用吧~
我觉得不要太拘泥于这些页面呈现细节上,我们程序员更应该专注于业务逻辑类的设计和架构研究...呵呵,说远了,我的目标而已

#12楼[楼主]   回复  引用  查看    

2007-04-20 10:31 by ColdDog      
@kiler
对了,你回复时有没有勾选底下的“有回复时邮件通知我”这个选项呢?
我怎么觉得这个功能不行了阿....求救中...

#13楼   回复  引用    

2007-04-20 11:23 by 跑步机[未注册用户]
学习了!!

#14楼[楼主]   回复  引用  查看    

2007-04-20 11:35 by ColdDog      
@跑步机
谢谢支持~

#15楼   回复  引用  查看    

2007-04-20 15:11 by dudu      
你用Gmail的邮箱试试。

#16楼[楼主]   回复  引用  查看    

2007-04-20 15:19 by ColdDog      
@dudu
谢谢dudu,我改成了gmail的邮箱就可以了,之前是用hotmail邮箱的,不过以前都可以的,只是最近忽然不行了......
呵呵,总算可以了,谢谢dudu~

#17楼   回复  引用  查看    

2007-04-22 17:15 by Jeffrey Zhao      
我也一直用hotmail的忽然就不行了

#18楼[楼主]   回复  引用  查看    

2007-04-22 19:40 by ColdDog      
@Jeffrey Zhao
:)
应该问问dudu,是不是和hotmail的邮箱有点冲突什么的了~



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 719866




相关文章:

相关链接: