ASP.Net2.0 数据绑定控件的优越性在哪里?
生活随笔
收集整理的這篇文章主要介紹了
ASP.Net2.0 数据绑定控件的优越性在哪里?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
盡管有豐富、功能強大的編程接口,ASP.NET?1.x?DataGrid?控件仍需要編寫大量自定義代碼來處理普通操作,如分頁、排序、編輯和刪除數據。例如,當用戶單擊以保存或取消更改時,DataGrid?控件能夠引發事件但不提供更多的功能。如果要將更改存儲到持續媒介(如一個數據庫)之中,則必須自己處理?UpdateCommand?事件,檢索更改后的值,編寫一條?SQL?命令,然后從該處提交更新。
DataGrid?控件限制普通數據操作的引發事件,因為它是一個數據源不可知的控件,能夠綁定到任何可枚舉的數據對象。執行數據操作(如更新或刪除)需要直接連接到一個特定的數據源。在?ASP.NET?1.x?中,則通過編寫特定于應用程序的?ADO.NET?代碼解決這個問題的。
ASP.NET?2.0?改進了數據綁定體系結構,引入了新的系列組件(數據源對象)作為數據綁定控件與?ADO.NET?對象之間的橋梁。這些源對象提升了一個略為不同的編程模型,提供了新功能和新成員。您的?ASP.NET?2.0?應用程序應該使用最新的網格控件?—?GridView,顯示數據報告。與之相似的?DataGrid?控件仍然支持,但?DataGrid?不能充分利用數據源組件的特定功能。
GridView?控件是?DataGrid?的接替者,并從幾個方面擴展了后者的功能。首先,它完全支持數據源組件,能夠自動處理諸如分頁、排序和編輯等數據操作,前提是綁定的數據源對象支持這些操作。另外,GridView?控件有一些比?DataGrid?優越的功能上的改進。特別是,它支持多個主鍵字段,公開了一些用戶界面的改進功能和一個處理與取消事件的新模型。
GridView?附帶了一對互補的視圖控件:DetailsView?和?FormView。通過這些控件的組合,您能夠輕松地建立主/詳細視圖,而只需少量代碼,有時根本不需要代碼。
GridView?與?DataGrid
ASP.NET?2.0?中數據綁定控件的類層次結構比?ASP.NET?1.x?中的更一致。在?2.0?版本中,所有控件無論有什么樣的實際實現過程和用戶界面特點,均從同一個基類(BaseDataBoundControl?類)派生。圖?1?顯示新的類關系圖。DataGrid?和其他?1.x?版本的控件(如?Repeater?和?DataList)沒有包含在該關系圖中。這些現有控件的繼承樹與?ASP.NET?1.x?的相同。特別是,Repeater?繼承了?WebControl,而?DataList?和?DataGrid?繼承了?BaseDataList。如圖?1?所示,GridView?是一個復合數據綁定控件,它與其他所有數據綁定控件(包括?DropDownList、DetailsView?和?ListBox)共享一組方法和屬性。
圖?1?ASP.NET?類關系圖
GridView?和?DataGrid?控件的高級功能相似,但基礎卻不同。GridView?盡可能地保留了?DataGrid?的對象模型,以便輕松地從現有頁面進行移植。但是,基于?DataGrid?的代碼與新的基于?GridView?的代碼不可能?100%?兼容。
DataGrid?與?GridView?控件的另一個主要差異在于自適應用戶界面。與?1.x?版本的?DataGrid?不同的是,GridView?也能在移動設備上顯示。換句話說,您能夠使用相同的用于桌面頁面的網格控件在移動設備上生成報告。2.0?版本的?DataGrid?也能自適應地顯示,但是它的?UI?功能沒有?GridView?豐富。
在?ASP.NET?2.0?中,改進后的?DataGrid?控件支持諸如主題和個性化等通用的控件功能。此外,新的?DataGrid?控件可由一個數據源控件填充。但要記住,綁定到數據源對象的?DataGrid?只能用于讀取數據。要實際修改底層數據源,仍然需要一些用戶定義的代碼。而?GridView?控件可以利用底層數據源的功能并自動刪除或更新記錄。注意,GridView?控件也支持傳統的基于?DataSource?屬性和?DataBind?方法的綁定機制。盡管完全支持這種綁定機制,但是不鼓勵使用這樣的編程實踐方法。
GridView?和數據源控件
那么,數據源控件是什么?我在?2004?年?6?月一期的?MSDN?Magazine?中詳細介紹了?ASP.NET?2.0?的這項流行的新功能。簡言之,一個數據源控件就是一組?Microsoft??.NET?Framework?類,它有利于數據存儲和數據綁定控件之間的雙向綁定。現有的控件(如?DataGrid)以及新的數據綁定控件(如?GridView),盡管綁定能力不同,但都能綁定到一個數據源。
一個數據源控件代表了數據源的主要功能:選擇、插入、更新和刪除。數據源控件能代表任何數據源:從關系數據源庫到?XML?文件,從流數據到業務對象。如果簡要介紹能讓您想起?.NET?的托管提供程序,請參見圖?2。
圖?2?數據源控件、GridView?和數據源
數據源控件可以位于一些?.NET?數據提供程序的上層,在數據綁定控件和數據源之間形成一個中間層。數據源控件也會公開一個提供基本操作的公共接口。一些數據綁定控件?—?特別是?GridView?控件,將這些命令與其他與數據有關的操作一起,綁定到適當的自動編輯。
數據源控件通過其屬性和方法,將綁定內容以一組命名的視圖形式公開。IDataSource?接口提供從數據源檢索數據視圖的基本功能集,所有數據源控件都實現了這個接口。ASP.NET?2.0?提供一些內置數據源控件,如圖?3?所列。圖?3列出的數據源控件屬于兩類:列表和分層組件。SiteMapDataSource?和?XmlDataSource?組件是分層數據源控件,用于像?TreeView?和?Menu?控件這樣的分層組件。其他各種組件用于管理列表數據。
圖?4?中的代碼說明如何在一個示例頁面上將?GridView?和?DataGrid?綁定到同一個數據源控件。在?ASP.NET?2.0?中,這是推薦的數據綁定方法。SqlDataSource?控件的特點是一個?ConnectionString?屬性加上?SelectCommand、UpdateCommand、InsertCommand?和?DeleteCommand?屬性的任意組合。所有屬性都是字符串形式,并且引用帶有可選參數的命令文本:?
<asp:SqlDataSource?runat="server"?
??ID="MySource"?
??ConnectionString="SERVER=(local);
??DATABASE=northwind;Integrated?Security=SSPI;"
??SelectCommand="SELECT?*?FROM?employees?WHERE?employeeid?>?@MinID">
??<SelectParameters>
?????<asp:ControlParameter?Name="MinID"?
??????????ControlId="EmpID"?
??????????PropertyName="Text"?/>
??</SelectParameters>
</asp:SqlDataSource>
?
每個數據源控件由唯一的?ID?表示。ID?是連結數據綁定控件和數據源控件之間的紐帶。通過?DataSourceId?屬性將?GridView?綁定到一個數據源控件。例如,每當網格需要獲取數據時,就執行與?SQLDataSource?控件相關聯的?SelectCommand?SQL?命令。當網格需要更新或刪除一條記錄時,就執行相應的?UpdateCommand?或?DeleteCommand?SQL?命令。如果不存在這樣的命令,則引發一個異常。在內部,當用戶刪除或更新一條記錄時,GridView?就像?1.x?版本的?DataGrid?一樣引發事件。但是與?DataGrid?不同的是,GridView?為這些事件定義內部的處理程序。默認的處理程序檢索綁定數據源定義的命令來處理和執行這些操作。圖?4說明,在保持網格顯示或更新數據的標記后無需編寫代碼。在更復雜的情況下,您可能需要編寫一些代碼。
圖?5?GridView?和?DataGrid
數據源控件和?GridView?控件通常用于無代碼數據綁定。圖?5?顯示圖?4的代碼生成的輸出結果。
在?ASP.NET?2.0?中,除了?DataSource?和?DataMember,DataGrid?還公開了?DataSourceId?屬性。DataSourceId?屬性將?DataGrid?連接到同一頁面上定義的一個合法數據源對象。但是,DataGrid?不提供與?GridView?同一級別的自動化操作。當用戶單擊以更新一條記錄時,DataGrid?引發?UpdateCommand?事件,而?GridView?除了引發?Updating?和?Updated?事件外,還檢索和執行數據源更新命令,允許用戶自定義發送到數據源控件的信息。
GridView?對象模型
GridView?與?DataGrid?的整體結果看起來相似。一些通用元素經過了重命名,一些通用功能現在需要不同的語法。總之,如果熟悉?DataGrid?控件,則可立即自如地運用?GridView。圖?6?詳盡列出了組成?GridView?的新元素(請注意,其中一些元素,如?DetailLinkStyle,僅用于在移動設備上顯示網格)。行元素通過?Rows?集合中的?GridViewRow?類生成的實例進行顯示。GridViewRow?類映射到?DataGridItem?類,而?Rows?明確替代了?DataGrid?的項目集合。行類型由?DataControlRowType?枚舉表示,用來指示位置和角色(例如,頁腳、頁眉、頁導航和數據行)。GridView?還引入一個新概念?—?行元素狀態。該行狀態由?DataControlRowState?標記的枚舉值表示?—?通常值是?Edit,可選值為?Insert?和?Selected。有趣的是,這兩類枚舉恰巧由所有數據視圖控件(GridView、DetailsView?和?FormView)共享。
除了引入符合自適應顯示的元素之外,GridView?僅有一個其他類型的新元素?—?空數據行。當?GridView?綁定到一個空數據源時,會選擇性地顯示一些默認內容,為用戶提供反饋。在這種情況下顯示的內容依賴于新的空數據行元素的內容。可通過一個屬性?(EmptyDataText)?或一個模板?(EmptyDataTemplate)?設置該行的內容。
GridView?控件的屬性主要分為三種類型:行為、可視設置和狀態。圖?7?列出?GridView?的一些屬性。請查看包括?EnableSortingAndPagingCallbacks、EmptyDataText?和?UseAccessibleHeader?在內的新屬性以及被重命名或改編的屬性,后者實現了?DataGrid?已經支持的功能。
編程模型與按鈕列略有不同。在?ASP.NET?1.x?的?DataGrid?中,您不得不通過添加特定的列類型來創建一個?Edit?按鈕?—?EditCommandColumn。如果要創建一個?Delete?或?Select?按鈕列,則必須添加通用的按鈕列并預定義一個命令名。GridView?對象則更一致、更簡潔。它基于三個新的布爾屬性:AutoGenerateEditButton、AutoGenerateDeleteButton?和?AutoGenerateSelectButton。當其中任何一個屬性設置為真時,網格中分別添加一個?Edit、Delete?或?Select?命令按鈕列。例如,當?AutoGenerateEditButton?屬性設置為真時,在網格中自動為每個數據行添加帶有?Edit?按鈕的一列。也可以手動添加這些按鈕,方法是在列集合中添加一個?CommandField?對象。Columns?屬性列出了列對象,這些對象很像?DataGrid?的?Columns?屬性列出的對象。根據客戶的反饋,其中也添加了幾個幫助器屬性。特別是,您現在能夠為每個顯示行存儲多個鍵值。實際上,DataGrid?的?DataKeyField?字符串屬性已經擴展為一個字段名數組。新的屬性命名為?DataKey,用于存儲由字段名組成的一個字符串數組,這個字符串數組唯一標識一個數據行。DataKey?是特定行的值的相應數組。它返回?DataKey?對象的集合。每個?DataKey?對象包含一個鍵名值,DataKey?的?DataKey?對象數量與?GridView?的顯示行數相同。
SortDirection?和?SortExpression?跟蹤當前的網格排序。這些屬性用于在內部實現自動翻轉排序,標記網格當前排序次序。每個對象的?PagerSettings?組包含配置用戶界面、行為和頁導航位置的所有屬性。現在,頁導航支持的導航模式不但包括首行和尾行,還包括下一行和上一行。
GridView?控件也能夠使用一個基于回調的輕量型機制來進行排序和分頁。您可以通過設置?EnableSortingAndPagingCallbacks?布爾屬性來開啟和關閉此功能。當單擊排序或分頁鏈接來啟用回調時,GridView?請求排序數據或下一頁,不回發可視頁面。(這里發生了一個往返過程,但是無頁面刷新,因此您不知道。)請注意,這個功能有個警告:啟用?GridView?中的選項時,新頁面保留當前選定的索引。如果有與之相關聯的詳細信息頁面,那么選定的內容將失去同步。處理類似?PageIndexChanging?這樣的事件也不管用,因為如果不啟用回調,則不能引發這些事件。最后,切記回調驅動的分頁和排序機制需要使用?Microsoft?Internet?Explorer?5.0?及更高版本。
GridView?事件
GridView?控件使用的方法與我們熟知的?DataBind?方法不同。在?ASP.NET?2.0?中,許多控件以及?Page?類本身使用的是?Pre-load/Post-load?事件對。控件生命周期中的關鍵操作被包裝在一對事件中,一個在操作發生前觸發,另一個在操作完成后立即觸發。GridView?類也是這樣。圖?8?顯示的是新事件列表。使用事件來通告操作極大地增強了編程能力。例如,通過掛鉤?RowUpdating?事件,您能夠檢查新值的更新內容。您可能想在客戶端提供的值存留到下層數據存儲之前,通過?HTML?編碼來處理?RowUpdating?事件。這種簡單的技巧有助于避免惡意的腳本注入。
使用?pre/post?事件對使您能夠取消一個基于運行時條件而進行的事件。請看以下代碼片段:?
void?PageIndexChanging(object?sender,?GridViewPageEventArgs?e)
{
??//?Is?this?the?sensitive?page??(>?4)
??bool?isSensitivePage?=?(e.NewPageIndex?>?4);
??if?(isSensitivePage?&&?(User.Identity.Name?!=?"username"))
?????e.Cancel?=?true;
??return;????
}
取消是一個讀/寫布爾屬性,存在于所有從?CancelEventArgs?派生的事件參數類中。GridView?的許多事件參數類繼承了?CancelEventArgs,這意味著所有這些事件都能被取消。Cancel?屬性值在激發“pre”事件時通常設置為假。處理事件時,您能夠檢查一些條件,通過將?Cancel?屬性設置為真選擇取消事件。例如,剛才的代碼片段在當前用戶未被授權查看索引大于?4?的頁面時,取消了轉換到新頁面的操作。?
顯示、排序和分頁
一個網格通常用于顯示數據庫查詢的結果。使用?GridView?控件顯示結果比以往更簡單。您只需建立一個數據源對象,提供連接字符串和查詢文本,為?GridView?的?DataSourceId?屬性分配數據源?ID。運行時,GridView?自動綁定到數據源,生成正確的數據列。在默認情況下,查詢的所有列均顯示在網格中。
像?DataGrid?控件一樣,GridView?也支持在?Columns?集合中自定義列字段。如果只想顯示檢索到的數據字段的一個子集,或只想自定義其顯示外觀,則可使用代表顯示數據列的對象來填充?Columns?集合。GridView?支持多種列類型,包括新的復選框和圖像列類型:?
<columns>
??<asp:boundfield?datafield="productname"?headertext="Product"?/>?
??<asp:checkboxfield?datafield="discontinued"?
?????headertext="Discontinued"?/>?
??<asp:buttonfield?buttontype="Button"?text="Buy"?/>?
??<asp:hyperlinkfield?text="More?Info..."?
?????datanavigateurlfields="productid,discontinued"
?????datanavigateurlformatstring="more.aspx?id={0}&disc={1}"?/>?
</columns>
?
圖?9?顯示的活動網格配置為使用代碼中列出的字段。GridView?列類名與?DataGrid?接口中的相應類名略有不同。后綴“column”基本被替換成后綴“field”。除了名字的更改,與列類匹配的行為幾乎相同。一些新的列類型使您不必經常使用模板。例如,CheckBoxField?列通過一個復選框顯示特定的數據字段,而改進的?HyperLinkField?列提供了期待已久的功能?—?支持多個?URL?參數。正如剛才的代碼片段所示,DataNavigateUrlFields?屬性接收了一個以逗號分隔的字段名列表,并將其合并到?DataNavigateUrlFormatString?屬性的文本中。?
圖?9?帶有活動字段的?GridView
請注意?ButtonField?與?CommandField?之間的差異。兩列都向網格的用戶界面添加了一個按鈕,但是?CommandField?用于顯示命令按鈕來執行選擇、編輯、插入或刪除操作。ButtonField?只是代表作為按鈕顯示的字段。最后,GridView?能夠通過?ImageField?列類型嵌入圖像。?
<asp:imagefield?datafield="photo"?headertext="Picture"?/>
圖?10?顯示活動的?ImageField?列,它位于?Northwind?雇員表的照片字段。有趣的是,ImageField?通過?ASP.NET?2.0?DynamicImage?控件顯示來自數據庫和?URL?兩者的圖像。而且,在編輯模式下,ImageField?列彈出一個?Browse?按鈕,用于定位要上載的位于本機的新文件。?
圖?10?圖像字段列
Template?列也受支持,所需的語法與?ASP.NET?1.x?的?DataGrid?使用的相似:?
<asp:templatefield?headertext="Product">
???<itemtemplate>
?????<b><%#?Eval("productname")%></b>?<br?/>
?????available?in?<%#?Eval("quantityperunit")%>
??</itemtemplate>
</asp:templatefield>
?
有趣的是,ASP.NET?2.0?允許的數據綁定表達式的語法更簡潔。在?ASP.NET?1.x?中生成模板化的內容需要使用下列表達式:?DataBinder.Eval(Container.DataItem,?"fieldname")由于使用了一個更小的數據綁定機制,現在,您能夠避免使用?DataBinder?類中靜態的?Eval?方法,而是調用?Page?類定義的新的?Eval?保護方法。您將計算的字段名和方法傳遞給?Eval,決定當前的數據項并通過?DataBinder.Eval?準備一個常規調用。?
Eval?被聲明為?TemplateControl?類的一個保護方法,Page?和?UserControl?都從這個類派生。真正代表一個?.aspx?活動頁面的類是從?Page?派生的一個類的實例;因此,它能夠調入受保護的方法。ASCX?用戶控件也是如此。
如果焦點是顯示純數據,則不需要像?GridView?這樣全新的網格控件。當然,現在您只需少量代碼或不需要編碼就能將數據源控件綁定到?GridView,但是單憑這點就有必要替換?DataGrid?嗎?如果答案是否定的,請考慮排序和分頁。
在?GridView?控件中,只需通過開啟?AllowPaging?和?AllowSorting?屬性就能啟用自動翻轉排序和分頁功能。如果在?ASP.NET?1.x?中嘗試過這項操作,您就可大概了解這項功能了。
圖?11?活動的可分頁、可排序網格
圖?11?顯示一個可分頁、可排序的網格。圖?12?顯示此網格的完整代碼。(值得注意的是,僅當需要標記列標頭來指示排序方向時才需要使用?C#?代碼。)因此,無需編寫代碼,排序和分頁就能十分正常地運行。通過?DataSourceMode?屬性控制?SQLDataSource?的數據檢索模型。可行的值類型是?DataSet(默認值)和?DataReader。當?DataSourceMode?為?DataSet?時,數據源控件可能會一直選擇性地緩存?SELECT?命令的結果。這使得?GridView?適應于豐富多樣的使用情境,其中控件可提供無代碼排序、篩選和分頁功能。默認情況下禁用緩存,因此它必須在數據源控件上啟用。
在內存中緩存數據能大大提高性能,但是數據會顯得有些脆弱。您必須權衡利弊,因為如果系統內存運行效率低,Cache?對象會自動丟棄最少使用的數據。此外,在?ASP.NET?2.0?中,SQLDataSource?控件可能選擇性地建立與數據庫的自動依賴關系,以便立即檢測到數據變更。這確保了總是顯示最新的數據。有關數據源控件功能的更多信息,請參見我在前面提到的?2004?年?6?月發表的文章。當?SQLDataSource?控件檢索模型為?DataReader?時,檢索數據使用?IDataReader?對象,它是一個只進、只讀、流水游標。
編輯數據
DataGrid?控件最大的缺點之一?—?相反卻是?GridView?控件最大的優點之一,是處理數據源更新的能力。當綁定數據源支持更新時,GridView?能夠自動執行數據操作,從而提供真正的出盒解決方案。數據源控件通過一些布爾屬性(例如?CanUpdate、CanDelete、CanSort?等)提供這些功能。
對?GridView?控件而言,數據編輯意味著就地編輯和記錄刪除。如前所述,就地編輯指網格支持更改當前顯示記錄的功能。啟用?GridView?的就地編輯,需要啟動?AutoGenerateEditButton?布爾屬性:?
<asp:gridview?runat="server"?id="MyGridView"?
???datasourceid="MySource"?
???autogenerateeditbutton="true">
???&S226;&S226;&S226;
</asp:gridview>
當?AutoGenerateEditButton?屬性設置為真時,GridView?顯示附加的一列,如圖?13?中最左邊一列。單擊一行的?Edit?按鈕將此行置于編輯模式下。當一行處于編輯模式下時,非只讀行的每個綁定字段將顯示適當的輸入控件,通常是一個?TextBox。當您單擊更新時,GridView?引發?RowUpdating?事件并檢查數據源的?CanUpdate?屬性。如果?CanUpdate?返回值為假,則引發一個異常。否則,在數據源對象的?UpdateCommand?屬性后創建和配置一個命令對象。
圖?13?GridView?的?Edit?列
即使您對?SQL?的操作僅限于定義命令結構?—?只定義語句而讓控件來完成其他操作,也無需使用?ADO.NET?或擔心如何使用命令或連接。想在用戶單擊?Update?時保留更改,可編寫以下代碼:?
<asp:sqldatasource?runat="server"?id="MySource"?
???connectionstring="SERVER=...;DATABASE=northwind;Integrated?
???Security=SSPI;"
???updatecommand="UPDATE?employees?SET
???????????firstname=@firstname,?lastname=@lastname?
???????????WHERE?employeeid=@employeeid">
</asp:sqldatasource>
<asp:gridview?runat="server"?id="MyGridView"?
???DataSourceId="MySource"?
???DataKeyNames="employeeid"?AutoGenerateEditButton="true">
???&S226;&S226;&S226;
</asp:gridview>
數據源的?UpdateCommand?屬性被設置為?GridView?使用的?SQL?命令。您能夠使用所需的任意數量的參數。如果您采用一種特殊的命名規則,參數值也能夠自動解析。代表更新字段的參數(例如?firstname)必須與網格列的?DataField?屬性名相匹配。用于標識工作記錄的?WHERE?子句中使用的參數必須與?DataKeyNames?屬性匹配,后者是顯示記錄的關鍵字段。最后,考慮這種情況:如果沒有定義?UpdateCommand,卻提交更改,那么?CanUpdate?返回值為假,并引發一個異常。RowUpdated?事件發出信號通知更新命令結束。通過更新命令更新的行數可在?RowUpdated?事件參數的?AffectedRows?屬性中檢索。
GridView?自動收集輸入字段的值,填充?name/value?對詞典,這個詞典指示了每個行字段的新值。GridView?也公開一個?RowUpdating?事件,允許您修改正在傳遞到數據源對象的值。此外,在相關數據源上激發?Update?操作前,GridView?將自動調用?Page.IsValid。如果?Page.IsValid?返回值為假,將取消操作。這對使用包括驗證程序在內的自定義編輯模板特別有用。
行刪除操作方式與此相似。下面的?SQL?命令是一個數據源對象的?DeleteCommand?屬性的合法內容:?
DELETE?employees?WHEREemployeeid=@employeeid請注意,如果由于特定于數據庫的約束而無法刪除記錄,刪除操作將失敗。例如,如果子記錄通過某種關系引用父記錄,父記錄將無法刪除。在這種情況下,引發一個異常。?
GridView?控件不自動支持向數據源插入數據。沒有這項功能完全是由于實現?GridView?不依賴于底層數據源的功能和特性。實際上,數據源對象提供一個?CanInsert?屬性并支持一個?InsertCommand?屬性。請注意,通過?GridView?和?DetailsView?控件的組合能夠實現這個功能,一會您就會了解到。
DetailsView?控件
許多應用程序需要一次作用于一條記錄。在?ASP.NET?1.x?中,沒有內置的功能支持這種情況。創建單條記錄視圖是可能的,但需要您自己編寫代碼。首先,您需要獲取記錄,然后,將字段綁定到數據綁定表單,選擇性地提供分頁按鈕來瀏覽記錄。我編寫了三個?Cutting?Edge?列的安裝程序來解決這個問題?—?2002?年?4?月、5?月和?6?月。
當生成主/詳細視圖時,經常需要顯示單條記錄的內容。通常,用戶從網格中選擇一條主記錄,讓應用程序追溯所有可用字段。通過組合?GridView?和?DetailsView,編寫少量代碼,就能夠生成有層次結構的視圖。
DetailsView?控件能夠自動綁定到任何數據源控件,使用其數據操作集。控件能夠自動分頁、更新、插入和刪除底層數據源的數據項,只要數據源支持這些操作。多數情況下,建立這些操作無需編寫代碼,如下所示:?
<asp:detailsview?runat="server"?id="det"?
???datasourceid="MySource"?
???autogenerateeditbutton="true"
???autogenerateinsertbutton="true"
???autogeneratedeletebutton="true"
???allowpaging="true"
???headertext="Employees">
???<pagersettings?mode="NextPreviousFirstLast"
??????firstpageimageurl="images/first.gif"?
??????lastpageimageurl="images/last.gif"?
??????nextpageimageurl="images/next.gif"?
??????previouspageimageurl="images/prev.gif"?/>?
</asp:detailsview>
?
DetailsView?控件的用戶界面能夠通過使用數據字段和類型進行自定義,其方式與?GridView?相似。DetailsView?不支持自定義模板,因為這項特殊的功能完全構造在新的?FormView?控件中。DetailsView?具有一個命令欄,顯示?Edit、Delete?和?New?按鈕的任意組合。當您單擊?Edit?或?New?時,控件顯示?Edit?或?Insert?模式,字段內容顯示在文本框中。工作模式能通過?Mode?和?DefaultMode?屬性控制。?
使用?DetailsView?控件能很好地實現無需代碼的主/詳細視圖。除了?Edit?和?Delete?按鈕,GridView?控件支持?Select?按鈕,它也是預定義的。通過設置?AutoGenerateSelectButton?屬性為真,您能為每一行啟用此按鈕。當用戶單擊此按鈕時,當前行輸入選定狀態,為?GridView?的?SelectedIndex?屬性分配從?0?開始的索引值。此外,GridView?控件引發?SelectedIndexChanged?事件。應用程序可以掛鉤到這個事件,并執行自定義代碼。
在?ASP.NET?2.0?中,如果您想生成主/詳細視圖,則無需處理?SelectedIndexChanged?事件。您可以將一個?GridView?控件和一個?DetailsView?控件拖放到頁面上,將兩者綁定到一個數據源。生成無代碼的主/詳細視圖的技巧是,將詳細視圖控件綁定到當前選定記錄所代表的數據源,如下所示:?
<asp:sqldatasource?runat="server"?id="MyDetailSource"????
???&S226;&S226;&S226;
???selectcommand="SELECT?*?FROM?customers"
???filterexpression="customerid='@customerid'">
???<filterparameters>
?????<asp:ControlParameter?Name="customerid"?
????????ControlId="masterGrid"?
????????PropertyName="SelectedValue"?/>
???</filterparameters>
</asp:sqldatasource>
?
數據源對象的?FilterExpression?屬性為?SelectCommand?指定的基礎查詢定義?WHERE?子句。參數值能夠以多種方式指定,包括直接綁定一個控件屬性。?對象將?@customerid?參數設置為主網格控件的?SelectedValue?屬性存儲的值。圖?14?的代碼顯示如何配置主網格控件和詳細視圖控件。圖?15?顯示活動頁面。請注意,無需程序代碼來完成這些功能。
圖?15?活動主網格
FormView?控件
FormView?是新的數據綁定控件,使用起來像是?DetailsView?的模板化版本。它每次從相關數據源中選擇一條記錄顯示,選擇性地提供分頁按鈕,用于在記錄之間移動。與?DetailsView?控件不同的是,FormView?不使用數據控件字段,而是允許用戶通過模板定義每個項目的顯示。FormView?支持其數據源提供的任何基本操作。
FormView?控件是作為通常使用的更新和插入接口而設計的,它不能驗證數據源架構,不支持高級編輯功能,比如外鍵字段下拉。然而,使用模板來提供此功能很容易。FormView?和?DetailsView?有兩方面的功能差異。首先,FormView?控件具有?ItemTemplate、EditItemTemplate?和?InsertItemTemplate?屬性,而?DetailsView?一個也沒有。其次,FormView?缺少命令行?—?將可用功能進行分組的工具欄。與?GridView?和?DetailsView?控件不同的是,FormView?沒有其自己默認的顯示布局。同時,它的圖形化布局完全是通過模板自定義的。因此,每個模板都包括特定記錄需要的所有命令按鈕。下列代碼片斷是在頁面中嵌入一個?FormView?的典型寫法。?
<asp:FormView?ID="EmpDetails"?runat="server"?
????DataSourceId="MySource"?AllowPaging="true">
????<ItemTemplate>
??????&S226;&S226;&S226;
????</ItemTemplate>
????<EditItemTemplate>
??????&S226;&S226;&S226;
????</EditItemTemplate>
????<InsertItemTemplate>
??????&S226;&S226;&S226;
????</InsertItemTemplate>
</asp:FormView>
?
圖?16?說明一個使用?FormView?控件的頁面。Edit?按鈕通過命令名?Edit?的?<asp:Button>?元素來添加。這將導致?FormView?從只讀模式轉換到編輯模式,使用定義過的?EditItemTemplate?顯示。New?命令名將強制控件轉換為插入模式,顯示?InsertItemTemplate?的定義內容。最后,如果您將命令名為?Delete?的按鈕添加到項目模板中,用戶單擊它時,FormView?將調用數據源的?Delete?命令。
圖?16?FormView?控件
如何檢索數據來更新或插入一條記錄?您可以使用一個新的數據綁定關鍵字?Bind,它是專門為雙向綁定而設計的:?
Bind?關鍵字像?Eval?一樣用于顯示數據,而且能在更新或插入一條記錄時檢索輸入值。此外,Bind?對?GridView?和?DetailsView?使用的?TemplateFields?非常有用。?
Bind?將綁定控件屬性值存入一個值集合,FormView?控件自動檢索和使用這個集合來組合插入或編輯命令的參數列表。傳遞到?Bind?的參數必須與數據容器的字段名匹配。例如,上一個代碼片斷中的文本框存放備注字段的值。最后,還要記住的是編輯和插入模板必須包含保存變更的按鈕。這是指普通的按鈕?—?用于保存的?Update?和?Insert?以及用于放棄操作的?Cancel。
FormView?事件的工作方式與?DetailsView?和?GridView?相同。因此,如果想處理像數據預處理或后處理(例如,填充下拉框)這樣更復雜的操作,您應該為?ItemCommand、ItemInserting?和?ModeChanging?之類的事件編寫適當的事件處理程序。
小結
數據綁定控件是大多數?Web?應用程序的必要組成部分。數據綁定控件應該簡單但功能強大。理想的情況是,它們應該以很少的單擊操作以及有限的代碼數量提供高級的功能。雖然?ASP.NET?2.0?仍然在使用,但是其新一代的數據綁定控件滿足了這個需求。ASP.NET?1.x?數據綁定的主要缺點是需要為普通數據操作編寫過多的代碼。這一點已經隨著數據源對象和?GridView?控件的引入而解決了。DetailsView?和?FormView?是對?GridView?的完美補充,代表了對?ASP.NET?1.x?數據工具箱的重大改進。
DataGrid?控件限制普通數據操作的引發事件,因為它是一個數據源不可知的控件,能夠綁定到任何可枚舉的數據對象。執行數據操作(如更新或刪除)需要直接連接到一個特定的數據源。在?ASP.NET?1.x?中,則通過編寫特定于應用程序的?ADO.NET?代碼解決這個問題的。
ASP.NET?2.0?改進了數據綁定體系結構,引入了新的系列組件(數據源對象)作為數據綁定控件與?ADO.NET?對象之間的橋梁。這些源對象提升了一個略為不同的編程模型,提供了新功能和新成員。您的?ASP.NET?2.0?應用程序應該使用最新的網格控件?—?GridView,顯示數據報告。與之相似的?DataGrid?控件仍然支持,但?DataGrid?不能充分利用數據源組件的特定功能。
GridView?控件是?DataGrid?的接替者,并從幾個方面擴展了后者的功能。首先,它完全支持數據源組件,能夠自動處理諸如分頁、排序和編輯等數據操作,前提是綁定的數據源對象支持這些操作。另外,GridView?控件有一些比?DataGrid?優越的功能上的改進。特別是,它支持多個主鍵字段,公開了一些用戶界面的改進功能和一個處理與取消事件的新模型。
GridView?附帶了一對互補的視圖控件:DetailsView?和?FormView。通過這些控件的組合,您能夠輕松地建立主/詳細視圖,而只需少量代碼,有時根本不需要代碼。
GridView?與?DataGrid
ASP.NET?2.0?中數據綁定控件的類層次結構比?ASP.NET?1.x?中的更一致。在?2.0?版本中,所有控件無論有什么樣的實際實現過程和用戶界面特點,均從同一個基類(BaseDataBoundControl?類)派生。圖?1?顯示新的類關系圖。DataGrid?和其他?1.x?版本的控件(如?Repeater?和?DataList)沒有包含在該關系圖中。這些現有控件的繼承樹與?ASP.NET?1.x?的相同。特別是,Repeater?繼承了?WebControl,而?DataList?和?DataGrid?繼承了?BaseDataList。如圖?1?所示,GridView?是一個復合數據綁定控件,它與其他所有數據綁定控件(包括?DropDownList、DetailsView?和?ListBox)共享一組方法和屬性。
圖?1?ASP.NET?類關系圖
GridView?和?DataGrid?控件的高級功能相似,但基礎卻不同。GridView?盡可能地保留了?DataGrid?的對象模型,以便輕松地從現有頁面進行移植。但是,基于?DataGrid?的代碼與新的基于?GridView?的代碼不可能?100%?兼容。
DataGrid?與?GridView?控件的另一個主要差異在于自適應用戶界面。與?1.x?版本的?DataGrid?不同的是,GridView?也能在移動設備上顯示。換句話說,您能夠使用相同的用于桌面頁面的網格控件在移動設備上生成報告。2.0?版本的?DataGrid?也能自適應地顯示,但是它的?UI?功能沒有?GridView?豐富。
在?ASP.NET?2.0?中,改進后的?DataGrid?控件支持諸如主題和個性化等通用的控件功能。此外,新的?DataGrid?控件可由一個數據源控件填充。但要記住,綁定到數據源對象的?DataGrid?只能用于讀取數據。要實際修改底層數據源,仍然需要一些用戶定義的代碼。而?GridView?控件可以利用底層數據源的功能并自動刪除或更新記錄。注意,GridView?控件也支持傳統的基于?DataSource?屬性和?DataBind?方法的綁定機制。盡管完全支持這種綁定機制,但是不鼓勵使用這樣的編程實踐方法。
GridView?和數據源控件
那么,數據源控件是什么?我在?2004?年?6?月一期的?MSDN?Magazine?中詳細介紹了?ASP.NET?2.0?的這項流行的新功能。簡言之,一個數據源控件就是一組?Microsoft??.NET?Framework?類,它有利于數據存儲和數據綁定控件之間的雙向綁定。現有的控件(如?DataGrid)以及新的數據綁定控件(如?GridView),盡管綁定能力不同,但都能綁定到一個數據源。
一個數據源控件代表了數據源的主要功能:選擇、插入、更新和刪除。數據源控件能代表任何數據源:從關系數據源庫到?XML?文件,從流數據到業務對象。如果簡要介紹能讓您想起?.NET?的托管提供程序,請參見圖?2。
圖?2?數據源控件、GridView?和數據源
數據源控件可以位于一些?.NET?數據提供程序的上層,在數據綁定控件和數據源之間形成一個中間層。數據源控件也會公開一個提供基本操作的公共接口。一些數據綁定控件?—?特別是?GridView?控件,將這些命令與其他與數據有關的操作一起,綁定到適當的自動編輯。
數據源控件通過其屬性和方法,將綁定內容以一組命名的視圖形式公開。IDataSource?接口提供從數據源檢索數據視圖的基本功能集,所有數據源控件都實現了這個接口。ASP.NET?2.0?提供一些內置數據源控件,如圖?3?所列。圖?3列出的數據源控件屬于兩類:列表和分層組件。SiteMapDataSource?和?XmlDataSource?組件是分層數據源控件,用于像?TreeView?和?Menu?控件這樣的分層組件。其他各種組件用于管理列表數據。
圖?4?中的代碼說明如何在一個示例頁面上將?GridView?和?DataGrid?綁定到同一個數據源控件。在?ASP.NET?2.0?中,這是推薦的數據綁定方法。SqlDataSource?控件的特點是一個?ConnectionString?屬性加上?SelectCommand、UpdateCommand、InsertCommand?和?DeleteCommand?屬性的任意組合。所有屬性都是字符串形式,并且引用帶有可選參數的命令文本:?
<asp:SqlDataSource?runat="server"?
??ID="MySource"?
??ConnectionString="SERVER=(local);
??DATABASE=northwind;Integrated?Security=SSPI;"
??SelectCommand="SELECT?*?FROM?employees?WHERE?employeeid?>?@MinID">
??<SelectParameters>
?????<asp:ControlParameter?Name="MinID"?
??????????ControlId="EmpID"?
??????????PropertyName="Text"?/>
??</SelectParameters>
</asp:SqlDataSource>
?
每個數據源控件由唯一的?ID?表示。ID?是連結數據綁定控件和數據源控件之間的紐帶。通過?DataSourceId?屬性將?GridView?綁定到一個數據源控件。例如,每當網格需要獲取數據時,就執行與?SQLDataSource?控件相關聯的?SelectCommand?SQL?命令。當網格需要更新或刪除一條記錄時,就執行相應的?UpdateCommand?或?DeleteCommand?SQL?命令。如果不存在這樣的命令,則引發一個異常。在內部,當用戶刪除或更新一條記錄時,GridView?就像?1.x?版本的?DataGrid?一樣引發事件。但是與?DataGrid?不同的是,GridView?為這些事件定義內部的處理程序。默認的處理程序檢索綁定數據源定義的命令來處理和執行這些操作。圖?4說明,在保持網格顯示或更新數據的標記后無需編寫代碼。在更復雜的情況下,您可能需要編寫一些代碼。
圖?5?GridView?和?DataGrid
數據源控件和?GridView?控件通常用于無代碼數據綁定。圖?5?顯示圖?4的代碼生成的輸出結果。
在?ASP.NET?2.0?中,除了?DataSource?和?DataMember,DataGrid?還公開了?DataSourceId?屬性。DataSourceId?屬性將?DataGrid?連接到同一頁面上定義的一個合法數據源對象。但是,DataGrid?不提供與?GridView?同一級別的自動化操作。當用戶單擊以更新一條記錄時,DataGrid?引發?UpdateCommand?事件,而?GridView?除了引發?Updating?和?Updated?事件外,還檢索和執行數據源更新命令,允許用戶自定義發送到數據源控件的信息。
GridView?對象模型
GridView?與?DataGrid?的整體結果看起來相似。一些通用元素經過了重命名,一些通用功能現在需要不同的語法。總之,如果熟悉?DataGrid?控件,則可立即自如地運用?GridView。圖?6?詳盡列出了組成?GridView?的新元素(請注意,其中一些元素,如?DetailLinkStyle,僅用于在移動設備上顯示網格)。行元素通過?Rows?集合中的?GridViewRow?類生成的實例進行顯示。GridViewRow?類映射到?DataGridItem?類,而?Rows?明確替代了?DataGrid?的項目集合。行類型由?DataControlRowType?枚舉表示,用來指示位置和角色(例如,頁腳、頁眉、頁導航和數據行)。GridView?還引入一個新概念?—?行元素狀態。該行狀態由?DataControlRowState?標記的枚舉值表示?—?通常值是?Edit,可選值為?Insert?和?Selected。有趣的是,這兩類枚舉恰巧由所有數據視圖控件(GridView、DetailsView?和?FormView)共享。
除了引入符合自適應顯示的元素之外,GridView?僅有一個其他類型的新元素?—?空數據行。當?GridView?綁定到一個空數據源時,會選擇性地顯示一些默認內容,為用戶提供反饋。在這種情況下顯示的內容依賴于新的空數據行元素的內容。可通過一個屬性?(EmptyDataText)?或一個模板?(EmptyDataTemplate)?設置該行的內容。
GridView?控件的屬性主要分為三種類型:行為、可視設置和狀態。圖?7?列出?GridView?的一些屬性。請查看包括?EnableSortingAndPagingCallbacks、EmptyDataText?和?UseAccessibleHeader?在內的新屬性以及被重命名或改編的屬性,后者實現了?DataGrid?已經支持的功能。
編程模型與按鈕列略有不同。在?ASP.NET?1.x?的?DataGrid?中,您不得不通過添加特定的列類型來創建一個?Edit?按鈕?—?EditCommandColumn。如果要創建一個?Delete?或?Select?按鈕列,則必須添加通用的按鈕列并預定義一個命令名。GridView?對象則更一致、更簡潔。它基于三個新的布爾屬性:AutoGenerateEditButton、AutoGenerateDeleteButton?和?AutoGenerateSelectButton。當其中任何一個屬性設置為真時,網格中分別添加一個?Edit、Delete?或?Select?命令按鈕列。例如,當?AutoGenerateEditButton?屬性設置為真時,在網格中自動為每個數據行添加帶有?Edit?按鈕的一列。也可以手動添加這些按鈕,方法是在列集合中添加一個?CommandField?對象。Columns?屬性列出了列對象,這些對象很像?DataGrid?的?Columns?屬性列出的對象。根據客戶的反饋,其中也添加了幾個幫助器屬性。特別是,您現在能夠為每個顯示行存儲多個鍵值。實際上,DataGrid?的?DataKeyField?字符串屬性已經擴展為一個字段名數組。新的屬性命名為?DataKey,用于存儲由字段名組成的一個字符串數組,這個字符串數組唯一標識一個數據行。DataKey?是特定行的值的相應數組。它返回?DataKey?對象的集合。每個?DataKey?對象包含一個鍵名值,DataKey?的?DataKey?對象數量與?GridView?的顯示行數相同。
SortDirection?和?SortExpression?跟蹤當前的網格排序。這些屬性用于在內部實現自動翻轉排序,標記網格當前排序次序。每個對象的?PagerSettings?組包含配置用戶界面、行為和頁導航位置的所有屬性。現在,頁導航支持的導航模式不但包括首行和尾行,還包括下一行和上一行。
GridView?控件也能夠使用一個基于回調的輕量型機制來進行排序和分頁。您可以通過設置?EnableSortingAndPagingCallbacks?布爾屬性來開啟和關閉此功能。當單擊排序或分頁鏈接來啟用回調時,GridView?請求排序數據或下一頁,不回發可視頁面。(這里發生了一個往返過程,但是無頁面刷新,因此您不知道。)請注意,這個功能有個警告:啟用?GridView?中的選項時,新頁面保留當前選定的索引。如果有與之相關聯的詳細信息頁面,那么選定的內容將失去同步。處理類似?PageIndexChanging?這樣的事件也不管用,因為如果不啟用回調,則不能引發這些事件。最后,切記回調驅動的分頁和排序機制需要使用?Microsoft?Internet?Explorer?5.0?及更高版本。
GridView?事件
GridView?控件使用的方法與我們熟知的?DataBind?方法不同。在?ASP.NET?2.0?中,許多控件以及?Page?類本身使用的是?Pre-load/Post-load?事件對。控件生命周期中的關鍵操作被包裝在一對事件中,一個在操作發生前觸發,另一個在操作完成后立即觸發。GridView?類也是這樣。圖?8?顯示的是新事件列表。使用事件來通告操作極大地增強了編程能力。例如,通過掛鉤?RowUpdating?事件,您能夠檢查新值的更新內容。您可能想在客戶端提供的值存留到下層數據存儲之前,通過?HTML?編碼來處理?RowUpdating?事件。這種簡單的技巧有助于避免惡意的腳本注入。
使用?pre/post?事件對使您能夠取消一個基于運行時條件而進行的事件。請看以下代碼片段:?
void?PageIndexChanging(object?sender,?GridViewPageEventArgs?e)
{
??//?Is?this?the?sensitive?page??(>?4)
??bool?isSensitivePage?=?(e.NewPageIndex?>?4);
??if?(isSensitivePage?&&?(User.Identity.Name?!=?"username"))
?????e.Cancel?=?true;
??return;????
}
取消是一個讀/寫布爾屬性,存在于所有從?CancelEventArgs?派生的事件參數類中。GridView?的許多事件參數類繼承了?CancelEventArgs,這意味著所有這些事件都能被取消。Cancel?屬性值在激發“pre”事件時通常設置為假。處理事件時,您能夠檢查一些條件,通過將?Cancel?屬性設置為真選擇取消事件。例如,剛才的代碼片段在當前用戶未被授權查看索引大于?4?的頁面時,取消了轉換到新頁面的操作。?
顯示、排序和分頁
一個網格通常用于顯示數據庫查詢的結果。使用?GridView?控件顯示結果比以往更簡單。您只需建立一個數據源對象,提供連接字符串和查詢文本,為?GridView?的?DataSourceId?屬性分配數據源?ID。運行時,GridView?自動綁定到數據源,生成正確的數據列。在默認情況下,查詢的所有列均顯示在網格中。
像?DataGrid?控件一樣,GridView?也支持在?Columns?集合中自定義列字段。如果只想顯示檢索到的數據字段的一個子集,或只想自定義其顯示外觀,則可使用代表顯示數據列的對象來填充?Columns?集合。GridView?支持多種列類型,包括新的復選框和圖像列類型:?
<columns>
??<asp:boundfield?datafield="productname"?headertext="Product"?/>?
??<asp:checkboxfield?datafield="discontinued"?
?????headertext="Discontinued"?/>?
??<asp:buttonfield?buttontype="Button"?text="Buy"?/>?
??<asp:hyperlinkfield?text="More?Info..."?
?????datanavigateurlfields="productid,discontinued"
?????datanavigateurlformatstring="more.aspx?id={0}&disc={1}"?/>?
</columns>
?
圖?9?顯示的活動網格配置為使用代碼中列出的字段。GridView?列類名與?DataGrid?接口中的相應類名略有不同。后綴“column”基本被替換成后綴“field”。除了名字的更改,與列類匹配的行為幾乎相同。一些新的列類型使您不必經常使用模板。例如,CheckBoxField?列通過一個復選框顯示特定的數據字段,而改進的?HyperLinkField?列提供了期待已久的功能?—?支持多個?URL?參數。正如剛才的代碼片段所示,DataNavigateUrlFields?屬性接收了一個以逗號分隔的字段名列表,并將其合并到?DataNavigateUrlFormatString?屬性的文本中。?
圖?9?帶有活動字段的?GridView
請注意?ButtonField?與?CommandField?之間的差異。兩列都向網格的用戶界面添加了一個按鈕,但是?CommandField?用于顯示命令按鈕來執行選擇、編輯、插入或刪除操作。ButtonField?只是代表作為按鈕顯示的字段。最后,GridView?能夠通過?ImageField?列類型嵌入圖像。?
<asp:imagefield?datafield="photo"?headertext="Picture"?/>
圖?10?顯示活動的?ImageField?列,它位于?Northwind?雇員表的照片字段。有趣的是,ImageField?通過?ASP.NET?2.0?DynamicImage?控件顯示來自數據庫和?URL?兩者的圖像。而且,在編輯模式下,ImageField?列彈出一個?Browse?按鈕,用于定位要上載的位于本機的新文件。?
圖?10?圖像字段列
Template?列也受支持,所需的語法與?ASP.NET?1.x?的?DataGrid?使用的相似:?
<asp:templatefield?headertext="Product">
???<itemtemplate>
?????<b><%#?Eval("productname")%></b>?<br?/>
?????available?in?<%#?Eval("quantityperunit")%>
??</itemtemplate>
</asp:templatefield>
?
有趣的是,ASP.NET?2.0?允許的數據綁定表達式的語法更簡潔。在?ASP.NET?1.x?中生成模板化的內容需要使用下列表達式:?DataBinder.Eval(Container.DataItem,?"fieldname")由于使用了一個更小的數據綁定機制,現在,您能夠避免使用?DataBinder?類中靜態的?Eval?方法,而是調用?Page?類定義的新的?Eval?保護方法。您將計算的字段名和方法傳遞給?Eval,決定當前的數據項并通過?DataBinder.Eval?準備一個常規調用。?
Eval?被聲明為?TemplateControl?類的一個保護方法,Page?和?UserControl?都從這個類派生。真正代表一個?.aspx?活動頁面的類是從?Page?派生的一個類的實例;因此,它能夠調入受保護的方法。ASCX?用戶控件也是如此。
如果焦點是顯示純數據,則不需要像?GridView?這樣全新的網格控件。當然,現在您只需少量代碼或不需要編碼就能將數據源控件綁定到?GridView,但是單憑這點就有必要替換?DataGrid?嗎?如果答案是否定的,請考慮排序和分頁。
在?GridView?控件中,只需通過開啟?AllowPaging?和?AllowSorting?屬性就能啟用自動翻轉排序和分頁功能。如果在?ASP.NET?1.x?中嘗試過這項操作,您就可大概了解這項功能了。
圖?11?活動的可分頁、可排序網格
圖?11?顯示一個可分頁、可排序的網格。圖?12?顯示此網格的完整代碼。(值得注意的是,僅當需要標記列標頭來指示排序方向時才需要使用?C#?代碼。)因此,無需編寫代碼,排序和分頁就能十分正常地運行。通過?DataSourceMode?屬性控制?SQLDataSource?的數據檢索模型。可行的值類型是?DataSet(默認值)和?DataReader。當?DataSourceMode?為?DataSet?時,數據源控件可能會一直選擇性地緩存?SELECT?命令的結果。這使得?GridView?適應于豐富多樣的使用情境,其中控件可提供無代碼排序、篩選和分頁功能。默認情況下禁用緩存,因此它必須在數據源控件上啟用。
在內存中緩存數據能大大提高性能,但是數據會顯得有些脆弱。您必須權衡利弊,因為如果系統內存運行效率低,Cache?對象會自動丟棄最少使用的數據。此外,在?ASP.NET?2.0?中,SQLDataSource?控件可能選擇性地建立與數據庫的自動依賴關系,以便立即檢測到數據變更。這確保了總是顯示最新的數據。有關數據源控件功能的更多信息,請參見我在前面提到的?2004?年?6?月發表的文章。當?SQLDataSource?控件檢索模型為?DataReader?時,檢索數據使用?IDataReader?對象,它是一個只進、只讀、流水游標。
編輯數據
DataGrid?控件最大的缺點之一?—?相反卻是?GridView?控件最大的優點之一,是處理數據源更新的能力。當綁定數據源支持更新時,GridView?能夠自動執行數據操作,從而提供真正的出盒解決方案。數據源控件通過一些布爾屬性(例如?CanUpdate、CanDelete、CanSort?等)提供這些功能。
對?GridView?控件而言,數據編輯意味著就地編輯和記錄刪除。如前所述,就地編輯指網格支持更改當前顯示記錄的功能。啟用?GridView?的就地編輯,需要啟動?AutoGenerateEditButton?布爾屬性:?
<asp:gridview?runat="server"?id="MyGridView"?
???datasourceid="MySource"?
???autogenerateeditbutton="true">
???&S226;&S226;&S226;
</asp:gridview>
當?AutoGenerateEditButton?屬性設置為真時,GridView?顯示附加的一列,如圖?13?中最左邊一列。單擊一行的?Edit?按鈕將此行置于編輯模式下。當一行處于編輯模式下時,非只讀行的每個綁定字段將顯示適當的輸入控件,通常是一個?TextBox。當您單擊更新時,GridView?引發?RowUpdating?事件并檢查數據源的?CanUpdate?屬性。如果?CanUpdate?返回值為假,則引發一個異常。否則,在數據源對象的?UpdateCommand?屬性后創建和配置一個命令對象。
圖?13?GridView?的?Edit?列
即使您對?SQL?的操作僅限于定義命令結構?—?只定義語句而讓控件來完成其他操作,也無需使用?ADO.NET?或擔心如何使用命令或連接。想在用戶單擊?Update?時保留更改,可編寫以下代碼:?
<asp:sqldatasource?runat="server"?id="MySource"?
???connectionstring="SERVER=...;DATABASE=northwind;Integrated?
???Security=SSPI;"
???updatecommand="UPDATE?employees?SET
???????????firstname=@firstname,?lastname=@lastname?
???????????WHERE?employeeid=@employeeid">
</asp:sqldatasource>
<asp:gridview?runat="server"?id="MyGridView"?
???DataSourceId="MySource"?
???DataKeyNames="employeeid"?AutoGenerateEditButton="true">
???&S226;&S226;&S226;
</asp:gridview>
數據源的?UpdateCommand?屬性被設置為?GridView?使用的?SQL?命令。您能夠使用所需的任意數量的參數。如果您采用一種特殊的命名規則,參數值也能夠自動解析。代表更新字段的參數(例如?firstname)必須與網格列的?DataField?屬性名相匹配。用于標識工作記錄的?WHERE?子句中使用的參數必須與?DataKeyNames?屬性匹配,后者是顯示記錄的關鍵字段。最后,考慮這種情況:如果沒有定義?UpdateCommand,卻提交更改,那么?CanUpdate?返回值為假,并引發一個異常。RowUpdated?事件發出信號通知更新命令結束。通過更新命令更新的行數可在?RowUpdated?事件參數的?AffectedRows?屬性中檢索。
GridView?自動收集輸入字段的值,填充?name/value?對詞典,這個詞典指示了每個行字段的新值。GridView?也公開一個?RowUpdating?事件,允許您修改正在傳遞到數據源對象的值。此外,在相關數據源上激發?Update?操作前,GridView?將自動調用?Page.IsValid。如果?Page.IsValid?返回值為假,將取消操作。這對使用包括驗證程序在內的自定義編輯模板特別有用。
行刪除操作方式與此相似。下面的?SQL?命令是一個數據源對象的?DeleteCommand?屬性的合法內容:?
DELETE?employees?WHEREemployeeid=@employeeid請注意,如果由于特定于數據庫的約束而無法刪除記錄,刪除操作將失敗。例如,如果子記錄通過某種關系引用父記錄,父記錄將無法刪除。在這種情況下,引發一個異常。?
GridView?控件不自動支持向數據源插入數據。沒有這項功能完全是由于實現?GridView?不依賴于底層數據源的功能和特性。實際上,數據源對象提供一個?CanInsert?屬性并支持一個?InsertCommand?屬性。請注意,通過?GridView?和?DetailsView?控件的組合能夠實現這個功能,一會您就會了解到。
DetailsView?控件
許多應用程序需要一次作用于一條記錄。在?ASP.NET?1.x?中,沒有內置的功能支持這種情況。創建單條記錄視圖是可能的,但需要您自己編寫代碼。首先,您需要獲取記錄,然后,將字段綁定到數據綁定表單,選擇性地提供分頁按鈕來瀏覽記錄。我編寫了三個?Cutting?Edge?列的安裝程序來解決這個問題?—?2002?年?4?月、5?月和?6?月。
當生成主/詳細視圖時,經常需要顯示單條記錄的內容。通常,用戶從網格中選擇一條主記錄,讓應用程序追溯所有可用字段。通過組合?GridView?和?DetailsView,編寫少量代碼,就能夠生成有層次結構的視圖。
DetailsView?控件能夠自動綁定到任何數據源控件,使用其數據操作集。控件能夠自動分頁、更新、插入和刪除底層數據源的數據項,只要數據源支持這些操作。多數情況下,建立這些操作無需編寫代碼,如下所示:?
<asp:detailsview?runat="server"?id="det"?
???datasourceid="MySource"?
???autogenerateeditbutton="true"
???autogenerateinsertbutton="true"
???autogeneratedeletebutton="true"
???allowpaging="true"
???headertext="Employees">
???<pagersettings?mode="NextPreviousFirstLast"
??????firstpageimageurl="images/first.gif"?
??????lastpageimageurl="images/last.gif"?
??????nextpageimageurl="images/next.gif"?
??????previouspageimageurl="images/prev.gif"?/>?
</asp:detailsview>
?
DetailsView?控件的用戶界面能夠通過使用數據字段和類型進行自定義,其方式與?GridView?相似。DetailsView?不支持自定義模板,因為這項特殊的功能完全構造在新的?FormView?控件中。DetailsView?具有一個命令欄,顯示?Edit、Delete?和?New?按鈕的任意組合。當您單擊?Edit?或?New?時,控件顯示?Edit?或?Insert?模式,字段內容顯示在文本框中。工作模式能通過?Mode?和?DefaultMode?屬性控制。?
使用?DetailsView?控件能很好地實現無需代碼的主/詳細視圖。除了?Edit?和?Delete?按鈕,GridView?控件支持?Select?按鈕,它也是預定義的。通過設置?AutoGenerateSelectButton?屬性為真,您能為每一行啟用此按鈕。當用戶單擊此按鈕時,當前行輸入選定狀態,為?GridView?的?SelectedIndex?屬性分配從?0?開始的索引值。此外,GridView?控件引發?SelectedIndexChanged?事件。應用程序可以掛鉤到這個事件,并執行自定義代碼。
在?ASP.NET?2.0?中,如果您想生成主/詳細視圖,則無需處理?SelectedIndexChanged?事件。您可以將一個?GridView?控件和一個?DetailsView?控件拖放到頁面上,將兩者綁定到一個數據源。生成無代碼的主/詳細視圖的技巧是,將詳細視圖控件綁定到當前選定記錄所代表的數據源,如下所示:?
<asp:sqldatasource?runat="server"?id="MyDetailSource"????
???&S226;&S226;&S226;
???selectcommand="SELECT?*?FROM?customers"
???filterexpression="customerid='@customerid'">
???<filterparameters>
?????<asp:ControlParameter?Name="customerid"?
????????ControlId="masterGrid"?
????????PropertyName="SelectedValue"?/>
???</filterparameters>
</asp:sqldatasource>
?
數據源對象的?FilterExpression?屬性為?SelectCommand?指定的基礎查詢定義?WHERE?子句。參數值能夠以多種方式指定,包括直接綁定一個控件屬性。?對象將?@customerid?參數設置為主網格控件的?SelectedValue?屬性存儲的值。圖?14?的代碼顯示如何配置主網格控件和詳細視圖控件。圖?15?顯示活動頁面。請注意,無需程序代碼來完成這些功能。
圖?15?活動主網格
FormView?控件
FormView?是新的數據綁定控件,使用起來像是?DetailsView?的模板化版本。它每次從相關數據源中選擇一條記錄顯示,選擇性地提供分頁按鈕,用于在記錄之間移動。與?DetailsView?控件不同的是,FormView?不使用數據控件字段,而是允許用戶通過模板定義每個項目的顯示。FormView?支持其數據源提供的任何基本操作。
FormView?控件是作為通常使用的更新和插入接口而設計的,它不能驗證數據源架構,不支持高級編輯功能,比如外鍵字段下拉。然而,使用模板來提供此功能很容易。FormView?和?DetailsView?有兩方面的功能差異。首先,FormView?控件具有?ItemTemplate、EditItemTemplate?和?InsertItemTemplate?屬性,而?DetailsView?一個也沒有。其次,FormView?缺少命令行?—?將可用功能進行分組的工具欄。與?GridView?和?DetailsView?控件不同的是,FormView?沒有其自己默認的顯示布局。同時,它的圖形化布局完全是通過模板自定義的。因此,每個模板都包括特定記錄需要的所有命令按鈕。下列代碼片斷是在頁面中嵌入一個?FormView?的典型寫法。?
<asp:FormView?ID="EmpDetails"?runat="server"?
????DataSourceId="MySource"?AllowPaging="true">
????<ItemTemplate>
??????&S226;&S226;&S226;
????</ItemTemplate>
????<EditItemTemplate>
??????&S226;&S226;&S226;
????</EditItemTemplate>
????<InsertItemTemplate>
??????&S226;&S226;&S226;
????</InsertItemTemplate>
</asp:FormView>
?
圖?16?說明一個使用?FormView?控件的頁面。Edit?按鈕通過命令名?Edit?的?<asp:Button>?元素來添加。這將導致?FormView?從只讀模式轉換到編輯模式,使用定義過的?EditItemTemplate?顯示。New?命令名將強制控件轉換為插入模式,顯示?InsertItemTemplate?的定義內容。最后,如果您將命令名為?Delete?的按鈕添加到項目模板中,用戶單擊它時,FormView?將調用數據源的?Delete?命令。
圖?16?FormView?控件
如何檢索數據來更新或插入一條記錄?您可以使用一個新的數據綁定關鍵字?Bind,它是專門為雙向綁定而設計的:?
Bind?關鍵字像?Eval?一樣用于顯示數據,而且能在更新或插入一條記錄時檢索輸入值。此外,Bind?對?GridView?和?DetailsView?使用的?TemplateFields?非常有用。?
Bind?將綁定控件屬性值存入一個值集合,FormView?控件自動檢索和使用這個集合來組合插入或編輯命令的參數列表。傳遞到?Bind?的參數必須與數據容器的字段名匹配。例如,上一個代碼片斷中的文本框存放備注字段的值。最后,還要記住的是編輯和插入模板必須包含保存變更的按鈕。這是指普通的按鈕?—?用于保存的?Update?和?Insert?以及用于放棄操作的?Cancel。
FormView?事件的工作方式與?DetailsView?和?GridView?相同。因此,如果想處理像數據預處理或后處理(例如,填充下拉框)這樣更復雜的操作,您應該為?ItemCommand、ItemInserting?和?ModeChanging?之類的事件編寫適當的事件處理程序。
小結
數據綁定控件是大多數?Web?應用程序的必要組成部分。數據綁定控件應該簡單但功能強大。理想的情況是,它們應該以很少的單擊操作以及有限的代碼數量提供高級的功能。雖然?ASP.NET?2.0?仍然在使用,但是其新一代的數據綁定控件滿足了這個需求。ASP.NET?1.x?數據綁定的主要缺點是需要為普通數據操作編寫過多的代碼。這一點已經隨著數據源對象和?GridView?控件的引入而解決了。DetailsView?和?FormView?是對?GridView?的完美補充,代表了對?ASP.NET?1.x?數據工具箱的重大改進。
轉載于:https://www.cnblogs.com/fubeidong/archive/2007/01/19/624518.html
總結
以上是生活随笔為你收集整理的ASP.Net2.0 数据绑定控件的优越性在哪里?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FTP中的收获
- 下一篇: 装AJAX.NET 1.0的环境,我遇到