盡管有豐富功能強大的編程接口ASPNET x DataGrid 控件仍需要編寫大量自定義代碼來處理普通操作如分頁排序編輯和刪除數據例如當用戶單擊以保存或取消更改時DataGrid 控件能夠引發事件但不提供更多的功能如果要將更改存儲到持續媒介(如一個數據庫)之中則必須自己處理 UpdateCommand 事件檢索更改後的值編寫一條 SQL 命令然後從該處提交更新
DataGrid 控件限制普通數據操作的引發事件因為它是一個數據源不可知的控件能夠綁定到任何可枚舉的數據對象執行數據操作(如更新或刪除)需要直接連接到一個特定的數據源在 ASPNET x 中則通過編寫特定於應用程序的 ADONET 代碼解決這個問題的
ASPNET 改進了數據綁定體系結構引入了新的系列組件(數據源對象)作為數據綁定控件與 ADONET 對象之間的橋梁這些源對象提升了一個略為不同的編程模型提供了新功能和新成員您的 ASPNET 應用程序應該使用最新的網格控件 — GridView顯示數據報告與之相似的 DataGrid 控件仍然支持但 DataGrid 不能充分利用數據源組件的特定功能
GridView 控件是 DataGrid 的接替者並從幾個方面擴展了後者的功能首先它完全支持數據源組件能夠自動處理諸如分頁排序和編輯等數據操作前提是綁定的數據源對象支持這些操作另外GridView 控件有一些比 DataGrid 優越的功能上的改進特別是它支持多個主鍵字段公開了一些用戶界面的改進功能和一個處理與取消事件的新模型
GridView 附帶了一對互補的視圖控件DetailsView 和 FormView通過這些控件的組合您能夠輕松地建立主/詳細視圖而只需少量代碼有時根本不需要代碼
GridView 與 DataGrid
ASPNET 中數據綁定控件的類層次結構比 ASPNET x 中的更一致在 版本中所有控件無論有什麼樣的實際實現過程和用戶界面特點均從同一個基類(BaseDataBoundControl 類)派生圖 顯示新的類關系圖DataGrid 和其他 x 版本的控件(如 Repeater 和 DataList)沒有包含在該關系圖中這些現有控件的繼承樹與 ASPNET x 的相同特別是Repeater 繼承了 WebControl而 DataList 和 DataGrid 繼承了 BaseDataList如圖 所示GridView 是一個復合數據綁定控件它與其他所有數據綁定控件(包括 DropDownListDetailsView 和 ListBox)共享一組方法和屬性
GridView 和 DataGrid 控件的高級功能相似但基礎卻不同GridView 盡可能地保留了 DataGrid 的對象模型以便輕松地從現有頁面進行移植但是基於 DataGrid 的代碼與新的基於 GridView 的代碼不可能 % 兼容
DataGrid 與 GridView 控件的另一個主要差異在於自適應用戶界面與 x 版本的 DataGrid 不同的是GridView 也能在移動設備上顯示換句話說您能夠使用相同的用於桌面頁面的網格控件在移動設備上生成報告 版本的 DataGrid 也能自適應地顯示但是它的 UI 功能沒有 GridView 豐富
在 ASPNET 中改進後的 DataGrid 控件支持諸如主題和個性化等通用的控件功能此外新的 DataGrid 控件可由一個數據源控件填充但要記住綁定到數據源對象的 DataGrid 只能用於讀取數據要實際修改底層數據源仍然需要一些用戶定義的代碼而 GridView 控件可以利用底層數據源的功能並自動刪除或更新記錄注意GridView 控件也支持傳統的基於 DataSource 屬性和 DataBind 方法的綁定機制盡管完全支持這種綁定機制但是不鼓勵使用這樣的編程實踐方法
GridView 和數據源控件
那麼數據源控件是什麼?我在 年 月一期的 MSDN?Magazine 中詳細介紹了 ASPNET 的這項流行的新功能簡言之一個數據源控件就是一組 Microsoft? NET Framework 類它有利於數據存儲和數據綁定控件之間的雙向綁定現有的控件(如 DataGrid)以及新的數據綁定控件(如 GridView)盡管綁定能力不同但都能綁定到一個數據源
一個數據源控件代表了數據源的主要功能選擇插入更新和刪除數據源控件能代表任何數據源從關系數據源庫到 XML 文件從流數據到業務對象如果簡要介紹能讓您想起 NET 的托管提供程序請參見圖
圖 數據源控件GridView 和數據源
數據源控件可以位於一些 NET 數據提供程序的上層在數據綁定控件和數據源之間形成一個中間層數據源控件也會公開一個提供基本操作的公共接口一些數據綁定控件 — 特別是 GridView 控件將這些命令與其他與數據有關的操作一起綁定到適當的自動編輯
數據源控件通過其屬性和方法將綁定內容以一組命名的視圖形式公開IDataSource 接口提供從數據源檢索數據視圖的基本功能集所有數據源控件都實現了這個接口ASPNET 提供一些內置數據源控件如圖 所列圖 列出的數據源控件屬於兩類列表和分層組件SiteMapDataSource 和 XmlDataSource 組件是分層數據源控件用於像 TreeView 和 Menu 控件這樣的分層組件其他各種組件用於管理列表數據
圖 中的代碼說明如何在一個示例頁面上將 GridView 和 DataGrid 綁定到同一個數據源控件在 ASPNET 中這是推薦的數據綁定方法SqlDataSource 控件的特點是一個 ConnectionString 屬性加上 SelectCommandUpdateCommandInsertCommand 和 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 就像 x 版本的 DataGrid 一樣引發事件但是與 DataGrid 不同的是GridView 為這些事件定義內部的處理程序默認的處理程序檢索綁定數據源定義的命令來處理和執行這些操作圖 說明在保持網格顯示或更新數據的標記後無需編寫代碼在更復雜的情況下您可能需要編寫一些代碼
圖 GridView 和 DataGrid
數據源控件和 GridView 控件通常用於無代碼數據綁定圖 顯示圖 的代碼生成的輸出結果
在 ASPNET 中除了 DataSource 和 DataMemberDataGrid 還公開了 DataSourceId 屬性DataSourceId 屬性將 DataGrid 連接到同一頁面上定義的一個合法數據源對象但是DataGrid 不提供與 GridView 同一級別的自動化操作當用戶單擊以更新一條記錄時DataGrid 引發 UpdateCommand 事件而 GridView 除了引發 Updating 和 Updated 事件外還檢索和執行數據源更新命令允許用戶自定義發送到數據源控件的信息
GridView 對象模型
GridView 與 DataGrid 的整體結果看起來相似一些通用元素經過了重命名一些通用功能現在需要不同的語法總之如果熟悉 DataGrid 控件則可立即自如地運用 GridView圖 詳盡列出了組成 GridView 的新元素(請注意其中一些元素如 DetailLinkStyle僅用於在移動設備上顯示網格)行元素通過 Rows 集合中的 GridViewRow 類生成的實例進行顯示GridViewRow 類映射到 DataGridItem 類而 Rows 明確替代了 DataGrid 的項目集合行類型由 DataControlRowType 枚舉表示用來指示位置和角色(例如頁腳頁眉頁導航和數據行)GridView 還引入一個新概念 — 行元素狀態該行狀態由 DataControlRowState 標記的枚舉值表示 — 通常值是 Edit可選值為 Insert 和 Selected有趣的是這兩類枚舉恰巧由所有數據視圖控件(GridViewDetailsView 和 FormView)共享
除了引入符合自適應顯示的元素之外GridView 僅有一個其他類型的新元素 — 空數據行當 GridView 綁定到一個空數據源時會選擇性地顯示一些默認內容為用戶提供反饋在這種情況下顯示的內容依賴於新的空數據行元素的內容可通過一個屬性 (EmptyDataText) 或一個模板 (EmptyDataTemplate) 設置該行的內容
GridView 控件的屬性主要分為三種類型行為可視設置和狀態圖 列出 GridView 的一些屬性請查看包括 EnableSortingAndPagingCallbacksEmptyDataText 和 UseAccessibleHeader 在內的新屬性以及被重命名或改編的屬性後者實現了 DataGrid 已經支持的功能
編程模型與按鈕列略有不同在 ASPNET x 的 DataGrid 中您不得不通過添加特定的列類型來創建一個 Edit 按鈕 — EditCommandColumn如果要創建一個 Delete 或 Select 按鈕列則必須添加通用的按鈕列並預定義一個命令名GridView 對象則更一致更簡潔它基於三個新的布爾屬性AutoGenerateEditButtonAutoGenerateDeleteButton 和 AutoGenerateSelectButton當其中任何一個屬性設置為真時網格中分別添加一個 EditDelete 或 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 及更高版本
GridView 事件
GridView 控件使用的方法與我們熟知的 DataBind 方法不同在 ASPNET 中許多控件以及 Page 類本身使用的是 Preload/Postload 事件對控件生命周期中的關鍵操作被包裝在一對事件中一個在操作發生前觸發另一個在操作完成後立即觸發GridView 類也是這樣圖 顯示的是新事件列表使用事件來通告操作極大地增強了編程能力例如通過掛鉤 RowUpdating 事件您能夠檢查新值的更新內容您可能想在客戶端提供的值存留到下層數據存儲之前通過 HTML 編碼來處理 RowUpdating 事件這種簡單的技巧有助於避免惡意的腳本注入
使用 pre/post 事件對使您能夠取消一個基於運行時條件而進行的事件請看以下代碼片段
void PageIndexChanging(object sender
GridViewPageEventArgs e)
{
// Is this the sensitive page? (>
)
bool isSensitivePage = (e
NewPageIndex >
);
if (isSensitivePage && (User
Identity
Name !=
username
))
e
Cancel = true;
return;
}
取消是一個讀/寫布爾屬性
存在於所有從 CancelEventArgs 派生的事件參數類中
GridView 的許多事件參數類繼承了 CancelEventArgs
這意味著所有這些事件都能被取消
Cancel 屬性值在激發
pre
事件時通常設置為假
處理事件時
您能夠檢查一些條件
通過將 Cancel 屬性設置為真選擇取消事件
例如
剛才的代碼片段在當前用戶未被授權查看索引大於
的頁面時
取消了轉換到新頁面的操作
顯示
排序和分頁
一個網格通常用於顯示數據庫查詢的結果
使用 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={
}&disc={
}
/>
</columns>
圖 顯示的活動網格配置為使用代碼中列出的字段GridView 列類名與 DataGrid 接口中的相應類名略有不同後綴column基本被替換成後綴field除了名字的更改與列類匹配的行為幾乎相同一些新的列類型使您不必經常使用模板例如CheckBoxField 列通過一個復選框顯示特定的數據字段而改進的 HyperLinkField 列提供了期待已久的功能 — 支持多個 URL 參數正如剛才的代碼片段所示DataNavigateUrlFields 屬性接收了一個以逗號分隔的字段名列表並將其合並到 DataNavigateUrlFormatString 屬性的文本中
圖 帶有活動字段的 GridView
請注意 ButtonField 與 CommandField 之間的差異兩列都向網格的用戶界面添加了一個按鈕但是 CommandField 用於顯示命令按鈕來執行選擇編輯插入或刪除操作ButtonField 只是代表作為按鈕顯示的字段最後GridView 能夠通過 ImageField 列類型嵌入圖像
<aspimagefield datafield=photo headertext=Picture />
圖 顯示活動的 ImageField 列它位於 Northwind 雇員表的照片字段有趣的是ImageField 通過 ASPNET DynamicImage 控件顯示來自數據庫和 URL 兩者的圖像而且在編輯模式下ImageField 列彈出一個 Browse 按鈕用於定位要上載的位於本機的新文件
圖 圖像字段列
Template 列也受支持所需的語法與 ASPNET x 的 DataGrid 使用的相似
<asp:templatefield headertext=Product>
<itemtemplate>
<b><%# Eval(productname)%></b> <br />
available in <%# Eval(quantityperunit)%>
</itemtemplate>
</asp:templatefield>
有趣的是ASPNET 允許的數據綁定表達式的語法更簡潔在 ASPNET x 中生成模板化的內容需要使用下列表達式 DataBinderEval(ContainerDataItem fieldname)由於使用了一個更小的數據綁定機制現在您能夠避免使用 DataBinder 類中靜態的 Eval 方法而是調用 Page 類定義的新的 Eval 保護方法您將計算的字段名和方法傳遞給 Eval決定當前的數據項並通過 DataBinderEval 准備一個常規調用
Eval 被聲明為 TemplateControl 類的一個保護方法Page 和 UserControl 都從這個類派生真正代表一個 aspx 活動頁面的類是從 Page 派生的一個類的實例因此它能夠調入受保護的方法ASCX 用戶控件也是如此
如果焦點是顯示純數據則不需要像 GridView 這樣全新的網格控件當然現在您只需少量代碼或不需要編碼就能將數據源控件綁定到 GridView但是單憑這點就有必要替換 DataGrid 嗎?如果答案是否定的請考慮排序和分頁
在 GridView 控件中只需通過開啟 AllowPaging 和 AllowSorting 屬性就能啟用自動翻轉排序和分頁功能如果在 ASPNET x 中嘗試過這項操作您就可大概了解這項功能了
圖 活動的可分頁可排序網格
圖 顯示一個可分頁可排序的網格圖 顯示此網格的完整代碼(值得注意的是僅當需要標記列標頭來指示排序方向時才需要使用 C# 代碼)因此無需編寫代碼排序和分頁就能十分正常地運行通過 DataSourceMode 屬性控制 SQLDataSource 的數據檢索模型可行的值類型是 DataSet(默認值)和 DataReader當 DataSourceMode 為 DataSet 時數據源控件可能會一直選擇性地緩存 SELECT 命令的結果這使得 GridView 適應於豐富多樣的使用情境其中控件可提供無代碼排序篩選和分頁功能默認情況下禁用緩存因此它必須在數據源控件上啟用
在內存中緩存數據能大大提高性能但是數據會顯得有些脆弱您必須權衡利弊因為如果系統內存運行效率低Cache 對象會自動丟棄最少使用的數據此外在 ASPNET 中SQLDataSource 控件可能選擇性地建立與數據庫的自動依賴關系以便立即檢測到數據變更這確保了總是顯示最新的數據有關數據源控件功能的更多信息請參見我在前面提到的 年 月發表的文章當 SQLDataSource 控件檢索模型為 DataReader 時檢索數據使用 IDataReader 對象它是一個只進只讀流水游標
編輯數據
DataGrid 控件最大的缺點之一 — 相反卻是 GridView 控件最大的優點之一是處理數據源更新的能力當綁定數據源支持更新時GridView 能夠自動執行數據操作從而提供真正的出盒解決方案數據源控件通過一些布爾屬性(例如 CanUpdateCanDeleteCanSort 等)提供這些功能
對 GridView 控件而言數據編輯意味著就地編輯和記錄刪除如前所述就地編輯指網格支持更改當前顯示記錄的功能啟用 GridView 的就地編輯需要啟動 AutoGenerateEditButton 布爾屬性
<asp:gridview runat=server id=MyGridView
datasourceid=MySource
autogenerateeditbutton=true>
&S;&S;&S;
</asp:gridview>
當 AutoGenerateEditButton 屬性設置為真時GridView 顯示附加的一列如圖 中最左邊一列單擊一行的 Edit 按鈕將此行置於編輯模式下當一行處於編輯模式下時非只讀行的每個綁定字段將顯示適當的輸入控件通常是一個 TextBox當您單擊更新時GridView 引發 RowUpdating 事件並檢查數據源的 CanUpdate 屬性如果 CanUpdate 返回值為假則引發一個異常否則在數據源對象的 UpdateCommand 屬性後創建和配置一個命令對象
圖 GridView 的 Edit 列
即使您對 SQL 的操作僅限於定義命令結構 — 只定義語句而讓控件來完成其他操作也無需使用 ADONET 或擔心如何使用命令或連接想在用戶單擊 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>
&S;&S;&S;
</asp:gridview>
數據源的 UpdateCommand 屬性被設置為 GridView 使用的 SQL 命令您能夠使用所需的任意數量的參數如果您采用一種特殊的命名規則參數值也能夠自動解析代表更新字段的參數(例如 firstname)必須與網格列的 DataField 屬性名相匹配用於標識工作記錄的 WHERE 子句中使用的參數必須與 DataKeyNames 屬性匹配後者是顯示記錄的關鍵字段最後考慮這種情況如果沒有定義 UpdateCommand卻提交更改那麼 CanUpdate 返回值為假並引發一個異常RowUpdated 事件發出信號通知更新命令結束通過更新命令更新的行數可在 RowUpdated 事件參數的 AffectedRows 屬性中檢索
GridView 自動收集輸入字段的值填充 name/value 對詞典這個詞典指示了每個行字段的新值GridView 也公開一個 RowUpdating 事件允許您修改正在傳遞到數據源對象的值此外在相關數據源上激發 Update 操作前GridView 將自動調用 PageIsValid如果 PageIsValid 返回值為假將取消操作這對使用包括驗證程序在內的自定義編輯模板特別有用
行刪除操作方式與此相似下面的 SQL 命令是一個數據源對象的 DeleteCommand 屬性的合法內容DELETE employees WHEREemployeeid=@employeeid請注意如果由於特定於數據庫的約束而無法刪除記錄刪除操作將失敗例如如果子記錄通過某種關系引用父記錄父記錄將無法刪除在這種情況下引發一個異常
GridView 控件不自動支持向數據源插入數據沒有這項功能完全是由於實現 GridView 不依賴於底層數據源的功能和特性實際上數據源對象提供一個 CanInsert 屬性並支持一個 InsertCommand 屬性請注意通過 GridView 和 DetailsView 控件的組合能夠實現這個功能一會您就會了解到
DetailsView 控件
許多應用程序需要一次作用於一條記錄在 ASPNET x 中沒有內置的功能支持這種情況創建單條記錄視圖是可能的但需要您自己編寫代碼首先您需要獲取記錄然後將字段綁定到數據綁定表單選擇性地提供分頁按鈕來浏覽記錄我編寫了三個 Cutting Edge 列的安裝程序來解決這個問題 — 年 月 月和 月
當生成主/詳細視圖時經常需要顯示單條記錄的內容通常用戶從網格中選擇一條主記錄讓應用程序追溯所有可用字段通過組合 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/firstgif
lastpageimageurl=images/lastgif
nextpageimageurl=images/nextgif
previouspageimageurl=images/prevgif />
</asp:detailsview>
DetailsView 控件的用戶界面能夠通過使用數據字段和類型進行自定義其方式與 GridView 相似DetailsView 不支持自定義模板因為這項特殊的功能完全構造在新的 FormView 控件中DetailsView 具有一個命令欄顯示 EditDelete 和 New 按鈕的任意組合當您單擊 Edit 或 New 時控件顯示 Edit 或 Insert 模式字段內容顯示在文本框中工作模式能通過 Mode 和 DefaultMode 屬性控制
使用 DetailsView 控件能很好地實現無需代碼的主/詳細視圖除了 Edit 和 Delete 按鈕GridView 控件支持 Select 按鈕它也是預定義的通過設置 AutoGenerateSelectButton 屬性為真您能為每一行啟用此按鈕當用戶單擊此按鈕時當前行輸入選定狀態為 GridView 的 SelectedIndex 屬性分配從 開始的索引值此外GridView 控件引發 SelectedIndexChanged 事件應用程序可以掛鉤到這個事件並執行自定義代碼
在 ASPNET 中如果您想生成主/詳細視圖則無需處理 SelectedIndexChanged 事件您可以將一個 GridView 控件和一個 DetailsView 控件拖放到頁面上將兩者綁定到一個數據源生成無代碼的主/詳細視圖的技巧是將詳細視圖控件綁定到當前選定記錄所代表的數據源如下所示
<asp:sqldatasource runat=server id=MyDetailSource
&S;&S;&S;
selectcommand=SELECT * FROM customers
filterexpression=customerid=@customerid>
<filterparameters>
<asp:ControlParameter Name=customerid
ControlId=masterGrid
PropertyName=SelectedValue />
</filterparameters>
</asp:sqldatasource>
對象的 FilterExpression 屬性為 SelectCommand 指定的基礎查詢定義 WHERE 子句參數值能夠以多種方式指定包括直接綁定一個控件屬性 對象將 @customerid 參數設置為主網格控件的 SelectedValue 屬性存儲的值圖 的代碼顯示如何配置主網格控件和詳細視圖控件圖 顯示活動頁面請注意無需程序代碼來完成這些功能
圖 活動主網格
FormView 控件
FormView 是新的數據綁定控件使用起來像是 DetailsView 的模板化版本它每次從相關數據源中選擇一條記錄顯示選擇性地提供分頁按鈕用於在記錄之間移動與 DetailsView 控件不同的是FormView 不使用數據控件字段而是允許用戶通過模板定義每個項目的顯示FormView 支持其數據源提供的任何基本操作
FormView 控件是作為通常使用的更新和插入接口而設計的它不能驗證數據源架構不支持高級編輯功能比如外鍵字段下拉然而使用模板來提供此功能很容易FormView 和 DetailsView 有兩方面的功能差異首先FormView 控件具有 ItemTemplateEditItemTemplate 和 InsertItemTemplate 屬性而 DetailsView 一個也沒有其次FormView 缺少命令行 — 將可用功能進行分組的工具欄與 GridView 和 DetailsView 控件不同的是FormView 沒有其自己默認的顯示布局同時它的圖形化布局完全是通過模板自定義的因此每個模板都包括特定記錄需要的所有命令按鈕下列代碼片斷是在頁面中嵌入一個 FormView 的典型寫法
<asp:FormView ID=EmpDetails runat=server
DataSourceId=MySource AllowPaging=true>
<ItemTemplate>
&S;&S;&S;
</ItemTemplate>
<EditItemTemplate>
&S;&S;&S;
</EditItemTemplate>
<InsertItemTemplate>
&S;&S;&S;
</InsertItemTemplate>
</asp:FormView>
圖 說明一個使用 FormView 控件的頁面Edit 按鈕通過命令名 Edit 的 <aspButton> 元素來添加這將導致 FormView 從只讀模式轉換到編輯模式使用定義過的 EditItemTemplate 顯示New 命令名將強制控件轉換為插入模式顯示 InsertItemTemplate 的定義內容最後如果您將命令名為 Delete 的按鈕添加到項目模板中用戶單擊它時FormView 將調用數據源的 Delete 命令
圖 FormView 控件
如何檢索數據來更新或插入一條記錄?您可以使用一個新的數據綁定關鍵字 Bind它是專門為雙向綁定而設計的Bind 關鍵字像 Eval 一樣用於顯示數據而且能在更新或插入一條記錄時檢索輸入值此外Bind 對 GridView 和 DetailsView 使用的 TemplateFields 非常有用
Bind 將綁定控件屬性值存入一個值集合FormView 控件自動檢索和使用這個集合來組合插入或編輯命令的參數列表傳遞到 Bind 的參數必須與數據容器的字段名匹配例如上一個代碼片斷中的文本框存放備注字段的值最後還要記住的是編輯和插入模板必須包含保存變更的按鈕這是指普通的按鈕 — 用於保存的 Update 和 Insert 以及用於放棄操作的 Cancel FormView 事件的工作方式與 DetailsView 和 GridView 相同因此如果想處理像數據預處理或後處理(例如填充下拉框)這樣更復雜的操作您應該為 ItemCommandItemInserting 和 ModeChanging 之類的事件編寫適當的事件處理程序
小結
數據綁定控件是大多數 Web 應用程序的必要組成部分數據綁定控件應該簡單但功能強大理想的情況是它們應該以很少的單擊操作以及有限的代碼數量提供高級的功能雖然 ASPNET 仍然在使用但是其新一代的數據綁定控件滿足了這個需求ASPNET x 數據綁定的主要缺點是需要為普通數據操作編寫過多的代碼這一點已經隨著數據源對象和 GridView 控件的引入而解決了DetailsView 和 FormView 是對 GridView 的完美補充代表了對 ASPNET x 數據工具箱的重大改進
From:http://tw.wingwit.com/Article/program/net/201311/13226.html