MOSS 2007開發中難免會碰到列表方式展現數據並進行翻頁功能的要求,MOSS 2007的對象模型中,實現翻頁的是SPListItemCollection的ListItemCollectionPosition屬性,但是這個屬性僅記錄和下一頁的起始位置,並沒有屬性來記錄上一頁的位置,所以實現上翻頁就比較麻煩了,而且只能一頁一頁的翻不能進行跳轉翻頁。如果要實現上述功能就要計算出所有頁面的起始位置然後在其中進行跳轉。

網上提供過一種變通的實現方式,就是先預讀出一部分數據作為前幾頁的數據來顯示,然後當用户需要看到其他部分的數據時,再翻到當前部分數據的最後一頁的時候,就去剩餘部分數據中再抽取一部分出來展示,這樣逐漸去一部分一部分抽取數據,根據的理論是“從統計學的角度講,用户一般比較關注前面的查詢結果,越到後面的頁查看的機會越小。因此,我們只需要先返回前面的頁即可。按照每頁顯示20-50行,一次最多顯示10頁,那麼返回的數據量大概在5000條以內。這個基本是可接受的範圍。因此,我們可以先獲得前10頁的數據,然後再進行分頁。至於要獲得後面的分頁,則可以在查看更多信息時獲得。”

搜了搜看着不像是原來那篇文章了,把地址貼下來,大家自己去看,裏面也説明了大數據量的一些處理方法和原理,包括實現的代碼示例。



 

這幾天同事在用.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
    {
        try
        {
            this.BindData1();
        }
        catch (Exception
        {
            Response.Write(ex.Message);
        }
    }
    private void
    {
        SPSite site = new SPSite("http://sc-learning:20000");
        SPWeb
        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

 
        this.GridView1.DataSource = items;
        this.GridView1.DataBind();
    }
    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs
    {
        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
    {
        try
        {
            this.BindData2();
        }
        catch (Exception
        {
            Response.Write(ex.Message);
        }
    }
    private void
    {
        SPSite site = new SPSite("http://sc-learning:20000");
        SPWeb
        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

 
        this.GridView2.DataSource = items;
        this.GridView2.DataBind();
    }
    protected void GridView2_PageIndexChanging(object sender, GridViewPageEventArgs
    {
        this.GridView2.PageIndex = e.NewPageIndex;
        this.BindData2();
    }
    protected void wibtn_Update_Click(object sender, ImageClickEventArgs
    {
        ClientScript.RegisterStartupScript(typeof(GridView), "ItemUpdate", "window.open('/Lists/List1/EditForm.aspx?ID=" + ((ImageButton)sender).CommandArgument.Trim() + @"');", true);
    }
    protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs
    {
        switch
        {
            case DataControlRowType.DataRow:
                SPSite site = new SPSite("http://sc-learning:20000");
                SPWeb
                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;
        }
    }

這樣就基本實現要求了。不要再去記錄翻頁位置,而且可以避免在進行查詢的同時數據更新造成的每頁起始位置變化數據不同步的問題。