在上一節我們主要介紹了Asp.net常用的數據綁定控件,在談到ListView控件時,我們說這是目前為止微軟封裝的功能最全的,最好用的數據綁定控件,ListView支持增、刪、改、排序、分頁,還可以自定義編寫的模板格式顯示數據。甚至如果你願意,你不用寫一行代碼就可以實現數據的綁定,這個控件實在在太簡單、太好用了。但是,我們要明白簡單好用的東西是要付出代價的,沒錯,雖然ListView有這么多的優點,但是仍然無法掩蓋它的性能劣勢,因為它需要一下子加載所有的數據,顯示在前台界面,同時會增加很多額外的東西增大服務器的壓力,ListView支持分頁,其分頁功能的實現需要配合分頁控件,它分頁的原理是將所有的數據從服務器中一下子讀出來,這樣無疑增大的服務器的壓力,有時候我們需要的僅僅是某一頁的數據,但是內置的分頁仍然會將所有的數據從數據庫中加載進來。所以ListView內置的分頁對於小數據量的數據還行,對於大量的數據則根本沒法用。
這一節里我們主要帶領大家實現ListView的高效分頁。Repeater是一個擁有很好的擴展性的數據綁定控件,用戶可以自定義顯示格式,但不足之處在於它不支持分頁,所以這一節里我也會向大家顯示如何實現ListView的分頁。
一、ListView高效分頁
首先我們新建一個Asp.net Web項目在Default.aspx頁拖放一個ListView控件,然后再拖放入一個ObjectDataSource作為數據源,頁面布局如下:
下面我們需要為ObjectDataSource位置數據源,在此之前我們要需要新建一個強類型的數據集,然后將數據庫中的Pserson表拖入數據集面板中,效果如下:
然后生成解決方案。這個時候就可以為ObjectDataSource設置數據源了,
設置的時候依次選擇:選擇業務對象里PsersonDSTableAdapters.PersonTableAdapter這一項,然后在下一步直接點擊完成即可。
完成了數據源的配置,這個時候我們需要對ListView進行數據綁定,
如圖示:
如果不想自定義的配置布局,可以點擊配置ListView,這里邊有已經布局好的方案,
如圖示:
確定選用的布局之后頁面呈現效果如下:
這個時候,我們已經實現了ListView的數據綁定展示,但是使用的分頁是ListView內置的分頁,根本不是我們要講的分頁,接下來才是我們要講的核心。細心的朋友可能都會發現在上邊生成強類型數據集PsersonDS中有兩個額外的配置函數:如圖示:
因此我們需要在添加兩個函數
一、GetCount函數,步驟如下:
1、PsersonDS的PsersonTableAdapter點擊右鍵添加查詢
2、選擇使用Sql語句,
3、選擇Select(返回單個值),
4、直接下一步,然后為該函數起一個名字GetCount,即為獲得數據庫中信息的條數。
二、GetAll函數,步驟如下:
1、2步如上
3、選擇Select(返回行)
4、寫下如下Sql語句。SELECT * from(select PID, PName, PSex, PAge, PJob,Row_number() over(order by PID) as rownum FROM dbo.Pserson) T where T.rownum>@startRowIndex and T.rownum<@startRowIndex+@maximunRows
5、然后為該函數起名為GetAll
請大家注意紅線標注的部分,這里邊用到Sql server里的Row_number()排序函數,該函數在sql server2005以后才有的函數,數據編輯器不支持Row_Number()函數,所以創建完成后需要在GetPageData屬性的parameters中添加兩個參數,參數名必須是startRowIndex和maximumRows這兩個,
添加步驟如下:在GetAll函數的屬性Parameter中添加
startRowIndex和maximumRows這兩個參數,參數類型為Int型,參數名必須為startRowIndex和maximumRows。在后邊會給大家解釋為什么必須是這兩個。
添加完以后我們需要把當前的解決方案再生成一下,以便得到及時的更新。
如圖:
前期的工作做好了,接下來需要我們在ListView中進行配置了,
先按照正常的步驟配置listview讓ListView自動生成Template再修改ObjectDataSource的EnablePaging=“true”,然后SelectCountMethod設置為取得行數的方法即GetCount方法
設置selectMode為GetAll
如圖示:
請大家注意紅線標注的部分,我們這里啟用了EnablePaging你可能會主要到這里邊有兩個屬性MaximumRowsParameterName和StartRowIndexParameterName吧,仔細看一下它們是不是和之前我們在GetAll函數中添加的兩個參數很像呢?沒錯,我們在GetAll里添加的兩個參數就是為這兩個屬性賦值。
好了,到這里為止你已經實現了ListView的高效分頁了,抓緊時間來體驗下吧。同樣對於GridView也可以用同樣的方式實現高效分頁,在這里就不多講了。高效分頁主要用到sql server中的Row_number() 函數,關於高效分頁的Sql 語句還有很多,有興趣的朋友可以參看我之前總結的文章《SQL語句全解析》,那里邊有對分頁的專門介紹,希望可以對大家有所幫助,還請多多指點!
二、Repeater高效分頁
Repeater是一個擴展性很好的控件,用戶可以自定義其要展示的內容格式,但是美中不足的是它不支持分頁、排序、編輯,僅提供重復模板內容,在實際運用中,我們大多用其來展示數據,但是如果數據量過大的時,這個時候就需要進行分頁處理,在本節里,我會帶領大家做一個Repeater的分頁處理。
首先新建一個.aspx頁在上面放置一個Repeater控件,頁面布局如下:
<div> <h1>Repeater分¤?頁°3</h1> <asp:Repeater ID="Repeater1" runat="server" > <FooterTemplate> </table> </FooterTemplate> <ItemTemplate> <tr> <td><asp:Label ID="Label1" runat="server" Text='<%#Eval("PName") %>'></asp:Label></td> <td><asp:Label ID="Label2" runat="server" Text='<%#Eval("PAge") %>'></asp:Label></td> <td><asp:Label ID="Label3" runat="server" Text='<%#Eval("PSex") %>'></asp:Label></td> <td><asp:Label ID="Label4" runat="server" Text='<%#Eval("PJob") %>'></asp:Label></td> </tr> </ItemTemplate> <HeaderTemplate> <table><tr><th>姓?名?</th><th>年¨º齡¢?</th><th>性?別Àe</th><th>工¡è作Á¡Â</th></tr> </HeaderTemplate> </asp:Repeater> <div id="fenye"> <asp:Label ID="lbNow" runat="server" Text="當Ì¡À前¡ã頁°3:êo"></asp:Label> <asp:Label ID="lbPage" runat="server" Text="1"></asp:Label> <asp:Label ID="lbAll" runat="server" Text="總Á¨¹頁°3數ºy:êo"></asp:Label> <asp:Label ID="lbCount" runat="server" Text=""></asp:Label> <asp:LinkButton ID="lbtnFirst" runat="server" onclick="lbtnFirst_Click">首º¡Á頁°3</asp:LinkButton> <asp:LinkButton ID="lbtnUp" runat="server" onclick="lbtnUp_Click">上¦?一°?頁°3</asp:LinkButton> <asp:LinkButton ID="lbtnDown" runat="server" onclick="lbtnDown_Click">下?一°?頁°3</asp:LinkButton> <asp:LinkButton ID="lbtnLast" runat="server" onclick="lbtnLast_Click">尾2頁°3</asp:LinkButton> <asp:DropDownList ID="DropDownList1" runat="server" Width="80px"> </asp:DropDownList> <asp:LinkButton ID="lbtnGo" runat="server" BackColor="LightBlue" BorderWidth="2px" BorderColor="Blue" onclick="lbtnGo_Click" style="width: 20px">Go</asp:LinkButton> </div> <br /> </div>
頁面布局如下:
由頁面布局可知,我們分別放置了四個LinkButton按鈕作為前后的導航,一個DropDownList文本框和一個button按鈕作為自由導航。
在.cs頁處理如下:
先新建一個全局的SqlConnection對象並實例化,然后新建一個SqlCommand對象
SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LinqTestConnectionString"].ToString()); public SqlCommand sqlCmd=null;
然后我們需要定義一個DropListBind()函數,在首次進入頁面時為DropDownList賦值
代碼如下:
public void DropListBind() { sqlConn.Open(); sqlCmd = new SqlCommand("select count(*) from Pserson", sqlConn);//獲取數據庫中信息的總條數 this.lbCount.Text = (Convert.ToInt32(sqlCmd.ExecuteScalar())/15).ToString();//每頁顯示15條,算出總頁數,並為DropDownList賦值 int[] num = new int[Convert.ToInt32(lbCount.Text)]; for (int i = 1; i <= Convert.ToInt32(lbCount.Text); i++) { num[i - 1] = i; } DropDownList1.DataSource = num; DropDownList1.DataBind(); }
接下來需要再創建一個函數用來管理首頁、上一頁、下一頁、尾頁四個按鈕的使用狀態
代碼如下:
public void State() { if (lbPage.Text == "1")//如果當前頁為第一頁,則前一頁和首頁按鈕禁用 { lbtnFirst.Enabled = false; lbtnUp.Enabled = false; lbtnLast.Enabled = true; lbtnDown.Enabled = true; } if (lbPage.Text == lbCount.Text)//如果當前頁為最后一頁,則后一頁和尾頁按鈕禁用 { lbtnFirst.Enabled = true; lbtnUp.Enabled = true; lbtnLast.Enabled = false; lbtnDown.Enabled = false; } if (Convert.ToInt32(lbPage.Text) > 1 && Convert.ToInt32(lbPage.Text) < Convert.ToInt32(lbCount.Text))
//如果當前也在首頁和尾頁之間則四個按鈕均可用 { lbtnFirst.Enabled = true; lbtnUp.Enabled = true; lbtnLast.Enabled = true; lbtnDown.Enabled = true; } }
然后,我們開始創建展示數據的函數,該函數的作用在於當用戶點擊按鈕時從數據庫中讀取不同的數據信息,和ListView內置的分頁效果不同,每次用戶點擊時,並不是一下子從數據庫加載所有的數據信息而是僅加載請求的那一頁的數據信息,這樣整個查詢的效率會相當高,服務器的壓力也會相對減小。
代碼如下:
public void Show() { sqlCmd = new SqlCommand("select * from Pserson where PID>'" + (Convert.ToInt32(lbPage.Text)-1)*15
+ "' and PID<='" + Convert.ToInt32(lbPage.Text)*15 + "' order by PID ASC", sqlConn);
//從數據庫中篩選信息,僅加載當前請求的那一頁的信息,效率會相對比較高,並非全部加載 SqlDataAdapter sAdapter = new SqlDataAdapter(sqlCmd); DataSet ds = new DataSet(); sAdapter.Fill(ds, "Result"); sqlConn.Close(); Repeater1.DataSource = ds.Tables["Result"]; Repeater1.DataBind(); }
做完這些准備工作之后,我們就要在Page_Load函數里邊做一些初始化的操作
代碼如下:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { DropListBind();//為DropDownList賦值 Show();//初始化顯示第一頁,默認當前為第一頁 State();//初始化導航按鈕的使用狀態 } }
接下來我們需要對四個導航按鈕做不同的處理,以便實現用戶的操作。
//首頁,只需將當前頁設置為1即可
protected void lbtnFirst_Click(object sender, EventArgs e) { lbPage.Text = "1"; Show(); State(); }
//前一頁,將當前頁的值減去一然后再賦值為當前頁即可
protected void lbtnUp_Click(object sender, EventArgs e) { lbPage.Text = (Convert.ToInt32(lbPage.Text) - 1).ToString(); Show(); State(); }
//后一頁,將當前頁的值加上一然后再賦值為當前頁即可
protected void lbtnDown_Click(object sender, EventArgs e) { lbPage.Text = (Convert.ToInt32(lbPage.Text) +1).ToString(); Show(); State(); }
//尾頁,將當前頁的值賦值為總頁數即可
protected void lbtnLast_Click(object sender, EventArgs e) { lbPage.Text =lbCount.Text; Show(); State(); }
//將當前頁的值賦值為DropDownList1所選值即可
protected void lbtnGo_Click(object sender, EventArgs e) { lbPage.Text = DropDownList1.SelectedValue; Show(); State(); }
好了,到這里我們已經實現了Repeater的高效分頁,因為只是一個演示的demo所以這里沒有用到存儲過程將這個查詢分頁語句進行封裝,在實際的開發過程中,我們應該專門寫一個存儲過程用來分頁。在這里我也寫了一個小的分頁方法供大家參考,這個方法主要是和本示例相搭配的。具體如下:
Create PROCEDURE dbo.DataPager ( @curPage int, @pageSize int ) AS select PName,PSex,PAge,PJob from Pserson where PID>(@curPage-1)*@pageSize and PID<@curPage*@pageSize order by PID ASC
我們通過實現Repeater的分頁,不難發現,其實我們完全可以把分頁做成一個用戶自定義的控件,來幫我們實現分頁。參照之前一個朋友的思路,我已經初步的實現了一個用戶自定義的分頁控件。還在完善后,后續會分享給大家。
這一節的學習就到這里了,希望能對大家有所幫助,還請多多指點!