MOSS 2007开发中难免会碰到列表方式展现数据并进行翻页功能的要求,MOSS 2007的对象模型中,实现翻页的是SPListItemCollection的ListItemCollectionPosition属性,但是这个属性仅记录和下一页的起始位置,并没有属性来记录上一页的位置,所以实现上翻页就比较麻烦了,而且只能一页一页的翻不能进行跳转翻页。如果要实现上述功能就要计算出所有页面的起始位置然后在其中进行跳转。
网上提供过一种变通的实现方式,就是先预读出一部分数据作为前几页的数据来显示,然后当用户需要看到其他部分的数据时,再翻到当前部分数据的最后一页的时候,就去剩余部分数据中再抽取一部分出来展示,这样逐渐去一部分一部分抽取数据,根据的理论是“从统计学的角度讲,用户一般比较关注前面的查询结果,越到后面的页查看的机会越小。因此,我们只需要先返回前面的页即可。按照每页显示20-50行,一次最多显示10页,那么返回的数据量大概在5000条以内。这个基本是可接受的范围。因此,我们可以先获得前10页的数据,然后再进行分页。至于要获得后面的分页,则可以在查看更多信息时获得。”
搜了搜看着不像是原来那篇文章了,把地址贴下来,大家自己去看,里面也说明了大数据量的一些处理方法和原理,包括实现的代码示例。
http://www.cnblogs.com/dotnba/archive/2007/11/19/964004.html
这几天同事在用.net开发的时候就问,为什么不用GridView自身的功能去实现呢,我一想,也是啊,GridView本身就能实现对数据的分页功能,为什么要把查询出来的数据在每次绑定的时候自己去处理呢,只要获取到的SPListItemCollection在赋给GridView的DataSource时能被GridView转换并识别就可以了啊,而且这也是个集合的类型,没什么问题啊。于是同事就去写了一段小代码来做实验,果然可以。
示例一:默认的数据绑定
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
onpageindexchanging="GridView1_PageIndexChanging">
<PagerStyle HorizontalAlign="Right" />
</asp:GridView>
protected void Page_Load(object sender, EventArgs e)
{
try
{
this.BindData1();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
private void BindData1()
{
SPSite site = new SPSite("http://sc-learning:20000");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["新闻列表"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"Created\" /><Value Type=\"DateTime\">2009-01-23T12:00:00Z</Value></Eq></Where>";
SPListItemCollection items = list.GetItems(query);
this.GridView1.DataSource = items;
this.GridView1.DataBind();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.GridView1.PageIndex = e.NewPageIndex;
this.BindData1();
}
就这样就简单的实现了查询后数据的分页,示例中实现的是查询列表中2009年1月23日后发布的新闻内容。
这个示例完成后,大家可以看到页面上展示出了SPListItem的所有内容,很多是我们不需要的,我们只需要展示自己需要的字段信息就好了。
示例二:展示自定义字段信息
<asp:GridView ID="GridView2" runat="server" AllowPaging="True"
AutoGenerateColumns="False"
onpageindexchanging="GridView2_PageIndexChanging"
onrowdatabound="GridView2_RowDataBound">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField HeaderText="来源" />
<asp:TemplateField HeaderText="GUID">
<ItemTemplate>
<asp:Label ID="wlabGuid" runat="server" Text='<%# Eval("ID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="序号">
<ItemStyle HorizontalAlign="Center" Width="10%" />
<ItemTemplate>
<asp:Label ID="lblnum" runat="server"><%#Container.DataItemIndex + 1%></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="标题">
<ItemStyle HorizontalAlign="Center" Width="80%" />
<ItemTemplate>
<a href='/Lists/List1/DispForm.aspx?ID=<%# Eval("ID")%>' target="_blank"><%# Eval("Title")%></a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="编辑">
<ItemStyle HorizontalAlign="Center" Width="10%" />
<ItemTemplate>
<asp:ImageButton ID="wibtn_Update" ImageUrl="~/Images/update.gif" runat="server"
CommandArgument='<%# Eval("ID")%>' onclick="wibtn_Update_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle HorizontalAlign="Right" />
</asp:GridView>
protected void Page_Load(object sender, EventArgs e)
{
try
{
this.BindData2();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
private void BindData2()
{
SPSite site = new SPSite("http://sc-learning:20000");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["新闻列表"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"Created\" /><Value Type=\"DateTime\">2009-01-23T12:00:00Z</Value></Eq></Where>";
SPListItemCollection items = list.GetItems(query);
this.GridView2.DataSource = items;
this.GridView2.DataBind();
}
protected void GridView2_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.GridView2.PageIndex = e.NewPageIndex;
this.BindData2();
}
protected void wibtn_Update_Click(object sender, ImageClickEventArgs e)
{
ClientScript.RegisterStartupScript(typeof(GridView), "ItemUpdate", "window.open('/Lists/List1/EditForm.aspx?ID=" + ((ImageButton)sender).CommandArgument.Trim() + @"');", true);
}
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
switch (e.Row.RowType)
{
case DataControlRowType.DataRow:
SPSite site = new SPSite("http://sc-learning:20000");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["新闻列表"];
SPListItem item = list.GetItemById(Convert.ToInt32(e.Row.Cells[0].Text.Trim()));
if (item["来源"] != null)
{
e.Row.Cells[1].Text = item["来源"].ToString();
}
break;
case DataControlRowType.EmptyDataRow:
break;
case DataControlRowType.Footer:
break;
case DataControlRowType.Header:
break;
case DataControlRowType.Pager:
break;
case DataControlRowType.Separator:
break;
default:
break;
}
}
这样就基本实现要求了。不要再去记录翻页位置,而且可以避免在进行查询的同时数据更新造成的每页起始位置变化数据不同步的问题。