用Gridview和ObjectDataSource轻松实现自定义分页
?一.什么是自定義分頁(yè)
??????? 自定義分頁(yè)是與默認(rèn)分頁(yè)相對(duì)應(yīng)的。默認(rèn)分頁(yè)指一次檢索出所有數(shù)據(jù)并將其綁定到數(shù)據(jù)綁定控件中,雖然該控件只能一頁(yè)一頁(yè)顯示這些數(shù)據(jù),但是所有數(shù)據(jù)其實(shí)都已經(jīng)被綁定到控件上了。自定義分頁(yè)的含義是顯示到哪一頁(yè)就檢索并綁定哪一頁(yè)的數(shù)據(jù)。顯然在大數(shù)據(jù)量的情況下,自定義分頁(yè)的效率會(huì)高很多。??
??????? 在Asp.net 1.x中自定義分頁(yè)又稱(chēng)數(shù)據(jù)庫(kù)分頁(yè),DataGrid中的AllowCustomerPaging屬性和VirtualItemCount屬性就是專(zhuān)門(mén)為自定義分頁(yè)準(zhǔn)備的。在Asp.net 2.0中因?yàn)橐肓藬?shù)據(jù)源的概念,因此自定義分頁(yè)也可以叫做數(shù)據(jù)源分頁(yè)。
二.為什么使用ObjectDataSource
??????? ASP.NET2.0提供了SqlDataSource數(shù)據(jù)源控件,提供了ConnectionString、SelectCommand、SelectCommandType、SelectParameters等屬性,分別用于指定連接字符串、SQL查詢語(yǔ)句、SQL查詢語(yǔ)句的類(lèi)型和查詢所使用的參數(shù)。SqlDataSource數(shù)據(jù)源控件根據(jù)這些屬性的設(shè)定從關(guān)系數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)。但是,SqlDataSource 控件存在一個(gè)問(wèn)題:該控件的缺點(diǎn)在于它迫使您將用戶界面層與數(shù)據(jù)訪問(wèn)層混合在一起,忽略了業(yè)務(wù)邏輯層。然而隨著應(yīng)用程序規(guī)模的擴(kuò)大,具有清晰的用戶界面層、業(yè)務(wù)邏輯層、數(shù)據(jù)訪問(wèn)層以及數(shù)據(jù)實(shí)體層是極為必要的。僅僅通過(guò) SqlDataSource 控件的屬性,在用戶界面層引用 SQL 語(yǔ)句或存儲(chǔ)過(guò)程是不可取的,或說(shuō)是缺乏架構(gòu)意識(shí)的,不利于代碼的重用和維護(hù)。另外,SqlDataSource也不支持?jǐn)?shù)據(jù)源分頁(yè),也就不能實(shí)現(xiàn)自定義分頁(yè)。
??????? ObjectDataSource 控件對(duì)象模型類(lèi)似于 SqlDataSource 控件。但ObjectDataSource 提供一個(gè) TypeName 屬性(而不是 ConnectionString屬性),該屬性指定用于執(zhí)行數(shù)據(jù)操作的業(yè)務(wù)邏輯類(lèi)的類(lèi)名,ObjectDataSource可以通過(guò)TypeName 屬性直接調(diào)用業(yè)務(wù)層的類(lèi)。類(lèi)似于 SqlDataSource 的命令屬性SelectCommand、InsertCommand、UpdateCommand、DeleteCommand,ObjectDataSource 控件支持諸如 SelectMethod、UpdateMethod、InsertMethod 和 DeleteMethod屬性,用于指定執(zhí)行這些操作的方法名。顯然ObjectDataSource是依托于一個(gè)業(yè)務(wù)邏輯類(lèi)的,這樣我們就可以擁有完善的架構(gòu),業(yè)務(wù)邏輯類(lèi)可以為復(fù)雜的業(yè)務(wù)邏輯提供好的支持,也有利于代碼的重用和維護(hù)。特別是ObjectDataSource 控件提供了EnablePaging屬性、SelectCountMethod屬性、StartRowIndexParameterName屬性和MaximumRowsParameterName屬性專(zhuān)門(mén)支持?jǐn)?shù)據(jù)源分頁(yè)。?SelectCountMethod屬性指定的是獲取數(shù)據(jù)項(xiàng)總數(shù)的方法。StartRowIndexParameterName屬性用于指定一個(gè)參數(shù)的名稱(chēng),如程序中不特別設(shè)定,其默認(rèn)參數(shù)名為startRowIndex,該參數(shù)代表該頁(yè)數(shù)據(jù)項(xiàng)的開(kāi)始行索引;MaximumRowsParameterName屬性也用于指定一個(gè)參數(shù)名稱(chēng),其默認(rèn)參數(shù)名為maximumRows,該參數(shù)代表一頁(yè)中容納的數(shù)據(jù)項(xiàng)總數(shù)。
三.示例
??????? 本例是以SQL Server自帶的Northwind數(shù)據(jù)庫(kù)的Orders表為主,Employees表和Customers表為輔,顯示OrderDate在1997年之前的Order列表。
(1). 實(shí)體層
??????? 在實(shí)體層中創(chuàng)建Order、Employee、Customer三個(gè)類(lèi),其中Order引用了Employee類(lèi)和Customer類(lèi)。
(2).??數(shù)據(jù)訪問(wèn)層
????????數(shù)據(jù)訪問(wèn)層使用了微軟提供的SqlHelper類(lèi)。
????{
????????private?string??ConnectionString?=?Convert.ToString(ConfigurationManager.ConnectionStrings["NorthWindConnectionString"]);
????????public?OrderDataAccess()
????????{
????????????//
????????????//?TODO:?Add?constructor?logic?here
????????????//
????????}
????????public?int?CountTotalNumber()
????????{
????????????return?Convert.ToInt32(SqlHelper.ExecuteScalar(ConnectionString,?CommandType.StoredProcedure,?"Order_Select_TotalNumber"));?
????????}
????????public?IEnumerable?FindOrders(int?startRowIndex,?int?maximumRows,bool?isDataSet)
????????{
????????????SqlParameter[]?parms?=?{
????????????????new?SqlParameter("@StartRowIndex",SqlDbType.Int,4),
????????????????new?SqlParameter("@MaximumRows",SqlDbType.Int,4)
????????????};
????????????parms[0].Value?=?startRowIndex;
????????????parms[1].Value?=?maximumRows;
????????????if(!isDataSet)
????????????{
????????????????ArrayList?OrderList?=?new?ArrayList();
????????????????using?(SqlDataReader?reader?=?SqlHelper.ExecuteReader(ConnectionString,?CommandType.StoredProcedure,?"Order_Select_Pagination",?parms))
????????????????{
????????????????????while?(reader.Read())
????????????????????{
????????????????????????OrderList.Add(LoadOrder(reader));
????????????????????}
????????????????}
????????????????return?OrderList;
????????????}
????????????else
????????????{
????????????????DataSet?ds?=?SqlHelper.ExecuteDataset(ConnectionString,?CommandType.StoredProcedure,?"Order_Select_Pagination",?parms);
????????????????return?ds.Tables[0].DefaultView;
????????????}
????????}
????????public?int?DeleteOrder(int?orderId)
????????{
????????????SqlParameter?parm?=?new?SqlParameter("@OrderID",SqlDbType.Int,4);
????????????parm.Value?=?orderId;
????????????return?SqlHelper.ExecuteNonQuery(ConnectionString,CommandType.StoredProcedure,"Order_Delete",parm);
????????}
????????private?Order?LoadOrder(SqlDataReader?reader)
????????{
????????????Order?order?=?new?Order();
????????????order.OrderId?=?Convert.ToInt32(reader["OrderID"]);
????????????order.Customer?=?new?Customer(Convert.ToString(reader["CustomerID"]),?Convert.ToString(reader["CompanyName"]));
????????????order.Employee?=?new?Employee(Convert.ToInt32(reader["EmployeeID"]),?Convert.ToString(reader["LastName"]),?Convert.ToString(reader["FirstName"]));
????????????order.OrderDate?=?Convert.ToDateTime(reader["OrderDate"]);
????????????order.RequiredDate?=?Convert.ToDateTime(reader["RequiredDate"]);
????????????order.ShippedDate?=?Convert.ToDateTime(reader["ShippedDate"]);
????????????order.ShipVia?=?Convert.ToInt32(reader["ShipVia"]);
????????????order.Freight?=?Convert.ToDecimal(reader["Freight"]);
????????????order.ShipName?=?Convert.ToString(reader["ShipName"]);
????????????order.ShipAddress?=?Convert.ToString(reader["ShipAddress"]);
????????????order.ShipCity?=?Convert.ToString(reader["ShipCity"]);
????????????order.ShipRegion?=?Convert.ToString(reader["ShipRegion"]);
????????????order.ShipPostalCode?=?Convert.ToString(reader["ShipPostalCode"]);
????????????order.ShipCountry?=?Convert.ToString(reader["ShipCountry"]);
????????????return?order;
????????}
????}
??????? 注意FindOrders方法,它帶有三個(gè)參數(shù),startRowIndex代表起始行的索引,maxmiumRows代表本次查詢所要獲得的數(shù)據(jù)項(xiàng)總數(shù),isDataSet是為標(biāo)示是使用DataSet還是SqlDataReader,如果表示層的GridView設(shè)置了屬性AllowSorting為true,也就是要求具有排序功能,那么數(shù)據(jù)訪問(wèn)層就必須使用DataSet來(lái)容納數(shù)據(jù),否則使用SqlDataReader就可以了。
(3). 存儲(chǔ)過(guò)程
獲取符合要求的總訂單數(shù)存儲(chǔ)過(guò)程:
ALTER?PROCEDURE?Order_Select_TotalNumber?AS
SET?NOCOUNT?ON
Select?Count(OrderID)
From?Orders?
Where?OrderDate?<?'1997'
RETURN?
分頁(yè)獲取數(shù)據(jù)的存儲(chǔ)過(guò)程:
ALTER?PROCEDURE?Order_Select_Pagination?(
????@StartRowIndex?int?=?null,
????@MaximumRows?int?=?null
)
AS
SET?NOCOUNT?ON
DECLARE?@PageLowerBound?int
DECLARE?@PageUpperBound?int
--?Set?the?page?bounds
SET?@PageLowerBound?=?@StartRowIndex
SET?@PageUpperBound?=?@PageLowerBound?+?@MaximumRows?+?1
--?Create?a?temp?table?to?store?the?select?results
CREATE?TABLE?#tmp
(
?????RecNo?int?IDENTITY?(1,?1)?NOT?NULL,
?????OrderID?int
)
INSERT?INTO?#tmp
????????SELECT?[OrderID]
????????FROM?[Orders]
????????Where?OrderDate?<?'1997'
????????ORDER?BY?OrderID?ASC
SELECT?o.*,e.LastName,e.FirstName,c.CompanyName
FROM?Orders?o?inner?join?Employees?e?on?o.EmployeeID?=?e.EmployeeID?inner?join?Customers?c?on?o.CustomerID?=?c.CustomerID,?#tmp?t
WHERE?o.OrderID?=?t.OrderID?AND
?????t.RecNo?>?@PageLowerBound?AND
?????t.RecNo?<?@PageUpperBound
ORDER?BY?t.RecNo
????RETURN
(4). 業(yè)務(wù)邏輯層
??????? 本例的業(yè)務(wù)邏輯很簡(jiǎn)單,只是作為表示層和數(shù)據(jù)訪問(wèn)層之間的橋梁,并沒(méi)有摻雜其它的運(yùn)算邏輯。
業(yè)務(wù)邏輯類(lèi)中的方法可以設(shè)置給ObjectDataSource控件的SelectCountMethod屬性和SelectMethod屬性,這樣ObjectDataSource就可以自動(dòng)通過(guò)業(yè)務(wù)邏輯類(lèi)獲得數(shù)據(jù)了。
????{
????????private?static?OrderDataAccess?orderAccess?=?new?OrderDataAccess();
????????
????????public?OrderBusinessLogic()
????????{
????????????//
????????????//?TODO:?Add?constructor?logic?here
????????????//
????????}
????????public?static?int?GetRowsTotalNumber()
????????{
????????????return?orderAccess.CountTotalNumber();
????????}
????????public?static?IEnumerable?GetOrdersForPagingAndSorting(int?startRowIndex,?int?maximumRows)
????????{
???????????return?orderAccess.FindOrders(startRowIndex,?maximumRows,true);??????????
????????}
????????public?static?IEnumerable?GetOrdersForPaging(int?startRowIndex,?int?maximumRows)
????????{
????????????return?orderAccess.FindOrders(startRowIndex,?maximumRows,?false);
????????}
????????public?static?void?DeleteOrder(int?orderId)
????????{
????????????orderAccess.DeleteOrder(orderId);
????????}???????
????}
???????值得注意的兩點(diǎn)是:第一,這里的方法都是用了靜態(tài)方法,其實(shí)也可以不使用靜態(tài)方法。不使用靜態(tài)方法時(shí)Asp.net會(huì)先實(shí)例化ObjectDataSource的TypeName中設(shè)定的類(lèi),然后調(diào)用它的方法。第二,GetOrdersForPagingAndSorting和GetOrdersForPaging兩個(gè)方法,前者是為了應(yīng)對(duì)GridView的排序要求,因?yàn)闉榱四軌驅(qū)崿F(xiàn)排序,必須使用DataView、DataTable或DataSet;而后者則不用于排序,只需返回一個(gè)SqlDataReader。
(5).頁(yè)面程序
??????? 如果想只使用下圖所示GridView的默認(rèn)分頁(yè)樣式,則按照下面的頁(yè)面代碼,不必再寫(xiě)任何后臺(tái)代碼就可實(shí)現(xiàn)。
???
????????????AllowPaging="true"?runat="server"?AllowSorting="true"?Width="720px"?PageSize="20">
????????????<PagerStyle?ForeColor="Blue"?BackColor="LightBlue"?/>????????????
????????????<Columns>
????????????????<asp:BoundField?HeaderText="Order?Id"?DataField="OrderId"??/>
????????????????<asp:TemplateField?HeaderText="Customer">
????????????????????<ItemTemplate>
????????????????????????<%#?Eval("Customer.CompanyName")%>
????????????????????</ItemTemplate>
????????????????</asp:TemplateField>
????????????????<asp:TemplateField?HeaderText="Employee">
????????????????????<ItemTemplate>
????????????????????????<%#?Eval("Employee.EmployeeName")%>
????????????????????</ItemTemplate>
????????????????</asp:TemplateField>
????????????????<asp:BoundField?HeaderText="Order?date"?DataField="OrderDate"?DataFormatString="{0:g}"?/>
????????????????<asp:BoundField?HeaderText="Required?date"?DataField="RequiredDate"?DataFormatString="{0:d}"?/>
????????????????<asp:BoundField?HeaderText="Shipped?date"?DataField="ShippedDate"?DataFormatString="{0:d}"?/>
????????????????<asp:BoundField?HeaderText="Ship?address"?DataField="ShipAddress"?/>
????????????????<asp:BoundField?HeaderText="Ship?country"?DataField="ShipCountry"?/>????????????????
????????????</Columns>
????????</asp:GridView>
????????<asp:ObjectDataSource?ID="OrdersObjectDataSource"?runat="server"?SelectCountMethod="GetRowsTotalNumber"
??????????SelectMethod="GetOrdersForPaging"?TypeName="MyTest.BusinessLogic.OrderBusinessLogic"?OldValuesParameterFormatString="Original_{0}"?EnablePaging="true">??????????
????????</asp:ObjectDataSource>
??????? 如果想實(shí)現(xiàn)如下圖所示的自定義的分頁(yè)樣式,則參考下列代碼:
????????????AllowPaging="true"?AllowSorting="true"?OnDataBound="OrdersGridView_DataBound"?runat="server"?
????????????Width="720px"?PageSize="25"?OnRowDeleted="OrdersGridView_RowDeleted"?DataKeyNames="OrderID">
????????????<Columns>
????????????????<asp:BoundField?HeaderText="Order?Id"?DataField="OrderID"?SortExpression="OrderID"/>
????????????????<asp:BoundField?HeaderText="Customer?company"?DataField="CompanyName"?SortExpression="CompanyName"/>
????????????????<asp:TemplateField?HeaderText="Employee"?SortExpression="EmployeeName">
??????????????????<ItemTemplate>
??????????????????????<%#?Eval("LastName")+"?"+Eval("FirstName")?%>??
??????????????????</ItemTemplate>
????????????????</asp:TemplateField>????????????????????????????????????????????????
????????????????<asp:BoundField?HeaderText="Order?date"?DataField="OrderDate"?DataFormatString="{0:g}"?SortExpression="OrderDate"/>
????????????????<asp:BoundField?HeaderText="Required?date"?DataField="RequiredDate"?DataFormatString="{0:d}"?SortExpression="RequiredDate"/>
????????????????<asp:BoundField?HeaderText="Shipped?date"?DataField="ShippedDate"?DataFormatString="{0:d}"?SortExpression="ShippedDate"/>
????????????????<asp:BoundField?HeaderText="Ship?address"?DataField="ShipAddress"?/>
????????????????<asp:BoundField?HeaderText="Ship?country"?DataField="ShipCountry"?/>????????????????
????????????????<asp:CommandField?ButtonType="Button"?DeleteText="刪除"?ShowDeleteButton="true"?HeaderText="Operation"??/>
????????????</Columns>
????????????<PagerStyle?ForeColor="Blue"?BackColor="LightBlue"?/>????????????
????????????<PagerTemplate>
????????????????<table?width="100%">
????????????????????<tr>
????????????????????????<td?width="70%">
????????????????????????????<asp:Label?ID="MessageLabel"?ForeColor="Blue"?Text="頁(yè)碼:"?runat="server"?/>
????????????????????????????<asp:DropDownList?ID="PageDropDownList"?AutoPostBack="true"?OnSelectedIndexChanged="PageDropDownList_SelectedIndexChanged"
????????????????????????????????runat="server"?/>
????????????????????????????<asp:LinkButton?CommandName="Page"?CommandArgument="First"?ID="linkBtnFirst"?runat="server">首頁(yè)</asp:LinkButton>
????????????????????????????<asp:LinkButton?CommandName="Page"?CommandArgument="Prev"?ID="linkBtnPrev"?runat="server">上一頁(yè)</asp:LinkButton>
????????????????????????????<asp:LinkButton?CommandName="Page"?CommandArgument="Next"?ID="linkBtnNext"?runat="server">下一頁(yè)</asp:LinkButton>
????????????????????????????<asp:LinkButton?CommandName="Page"?CommandArgument="Last"?ID="linkBtnLast"?runat="server">末頁(yè)</asp:LinkButton>
????????????????????????</td>
????????????????????????<td?align="right">
????????????????????????????<asp:Label?ID="CurrentPageLabel"?ForeColor="Blue"?runat="server"?/>
????????????????????????</td>
????????????????????</tr>
????????????????</table>
????????????</PagerTemplate>
????????</asp:GridView>
????????<asp:ObjectDataSource?ID="OrdersObjectDataSource"?runat="server"?SelectCountMethod="GetRowsTotalNumber"
??????????SelectMethod="GetOrdersForPagingAndSorting"?DeleteMethod="DeleteOrder"
??????????TypeName="MyTest.BusinessLogic.OrderBusinessLogic"?EnablePaging="true"?EnableViewState="true">??????????
????????<DeleteParameters>
????????????<asp:Parameter?Name="OrderId"?Type="Int32"?Direction="Input"?/>
????????</DeleteParameters>
????????</asp:ObjectDataSource>
??????? 注意頁(yè)導(dǎo)航模板PagerTemplate屬性的使用。通常將按鈕控件(如上面代碼中的LinkButton)添加到頁(yè)導(dǎo)航模板以執(zhí)行分頁(yè)操作。單擊 CommandName 屬性設(shè)置為“Page”的按鈕控件時(shí),GridView 控件會(huì)執(zhí)行分頁(yè)操作。按鈕的 CommandArgument 屬性確定要執(zhí)行的分頁(yè)操作的類(lèi)型。下表列出了 GridView 控件支持的命令參數(shù)值。?
| “Next” | 導(dǎo)航至下一頁(yè)。 |
| “Prev” | 導(dǎo)航至上一頁(yè)。 |
| “First” | 導(dǎo)航至第一頁(yè)。 |
| “Last” | 導(dǎo)航至最后一頁(yè)。 |
| 整數(shù)值 | 導(dǎo)航至指定頁(yè)碼。 |
??????? 頁(yè)面程序的后臺(tái)代碼:
public?partial?class?TestGridview2?:?System.Web.UI.Page{
????protected?void?Page_Load(object?sender,?EventArgs?e)
????{
????}
????protected?void?PageDropDownList_SelectedIndexChanged(Object?sender,?EventArgs?e)
????{
????????GridViewRow?pagerRow?=?OrdersGridView.BottomPagerRow;
????????DropDownList?pageList?=?(DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
????????OrdersGridView.PageIndex?=?pageList.SelectedIndex;
????}
????protected?void?OrdersGridView_DataBound(Object?sender,?EventArgs?e)
????{
????????GridViewRow?pagerRow?=?OrdersGridView.BottomPagerRow;
????????LinkButton?linkBtnFirst?=?(LinkButton)pagerRow.Cells[0].FindControl("linkBtnFirst");
????????LinkButton?linkBtnPrev?=?(LinkButton)pagerRow.Cells[0].FindControl("linkBtnPrev");
????????LinkButton?linkBtnNext?=?(LinkButton)pagerRow.Cells[0].FindControl("linkBtnNext");
????????LinkButton?linkBtnLast?=?(LinkButton)pagerRow.Cells[0].FindControl("linkBtnLast");
????????if?(OrdersGridView.PageIndex?==?0)
????????{
????????????linkBtnFirst.Enabled?=?false;
????????????linkBtnPrev.Enabled?=?false;
????????}
????????else?if?(OrdersGridView.PageIndex?==?OrdersGridView.PageCount?-?1)
????????{
????????????linkBtnLast.Enabled?=?false;
????????????linkBtnNext.Enabled?=?false;
????????}
????????else?if?(OrdersGridView.PageCount?<=?0)
????????{
????????????linkBtnFirst.Enabled?=?false;
????????????linkBtnPrev.Enabled?=?false;
????????????linkBtnNext.Enabled?=?false;
????????????linkBtnLast.Enabled?=?false;
????????}
????????DropDownList?pageList?=?(DropDownList)pagerRow.Cells[0].FindControl("PageDropDownList");
????????Label?pageLabel?=?(Label)pagerRow.Cells[0].FindControl("CurrentPageLabel");
????????if?(pageList?!=?null)
????????{
????????????for?(int?i?=?0;?i?<?OrdersGridView.PageCount;?i++)
????????????{
????????????????int?pageNumber?=?i?+?1;
????????????????ListItem?item?=?new?ListItem(pageNumber.ToString()?+?"/"?+?OrdersGridView.PageCount.ToString(),?pageNumber.ToString());
????????????????if?(i?==?OrdersGridView.PageIndex)
????????????????{
????????????????????item.Selected?=?true;
????????????????}
????????????????pageList.Items.Add(item);
????????????}
????????}
????????if?(pageLabel?!=?null)
????????{
????????????int?currentPage?=?OrdersGridView.PageIndex?+?1;
????????????pageLabel.Text?=?"當(dāng)前頁(yè):?"?+?currentPage.ToString()?+
??????????????"?/?"?+?OrdersGridView.PageCount.ToString();
????????}
????}
????protected?void?OrdersGridView_RowDeleted(object?sender,GridViewDeletedEventArgs?e)
????{
????????if?(e.Exception?==?null?&&?OrdersGridView.Rows.Count?==?1)
????????{
????????????//?we?just?deleted?the?last?row
????????????OrdersGridView.PageIndex?=?Math.Max(0,?OrdersGridView.PageIndex?-?1);
?????????}
????}
}
????
??? 由以上示例可以看出GridView關(guān)聯(lián)ObjectDataSource時(shí),省去了DataBind方法的使用。也就是說(shuō)只要給GridView關(guān)聯(lián)上數(shù)據(jù)源控件,那么綁定的事程序員就不用操心了。當(dāng)GridView發(fā)生翻頁(yè)事件時(shí)整個(gè)的運(yùn)行過(guò)程是這樣的,GridView的PageIndex變成新值,ObjectDataSource根據(jù)GridView的PageIndex屬性換算出startRowIndex和MaxmiumRows的值,然后傳遞這兩個(gè)參數(shù)給SelectMethod指定的方法從而獲得數(shù)據(jù),然后再調(diào)用SelectCountMethod指定的方法獲得總數(shù)據(jù)項(xiàng)數(shù),以計(jì)算出總頁(yè)數(shù),然后執(zhí)行OrderGridView_DataBound事件處理方法最終完成綁定工作。
??? 注意OrdersGridView_RowDeleted事件處理方法的寫(xiě)法,它是為了應(yīng)對(duì)將最后一頁(yè)的最后一條數(shù)據(jù)刪除之后,GridView將能夠識(shí)別出最后一頁(yè)已經(jīng)被刪空了,因此原來(lái)的倒數(shù)第二頁(yè)就變成了現(xiàn)在的末頁(yè)了,并讓GridView的當(dāng)前頁(yè)指向末頁(yè)。
????下載完整源程序/Files/taewind/TestDataBindControlls.rar
總結(jié)
以上是生活随笔為你收集整理的用Gridview和ObjectDataSource轻松实现自定义分页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: moment.js插件的简单上手使用
- 下一篇: GBin1分享的10个吸引眼球的jQue