日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

使用 ASP+ DataGrid 控件来创建主视图/详细资料视图

發(fā)布時間:2023/11/27 生活经验 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 ASP+ DataGrid 控件来创建主视图/详细资料视图 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Nikhil Kothari
Microsoft Corporation
2000年8月

簡介

Microsoft? Visual Studio.NET 的下一發(fā)行版包括 DataGrid Web 控件 (作為服務(wù)器控件的 Active Server Page+ (ASP+) 套件的一部分)。 該控件提供用以根據(jù)數(shù)據(jù)源的內(nèi)容來表示 HTML 的功能。

DataGrid 控件可以用于若干個只讀匯報情形。該控件設(shè)計用于對豐富而完全可定制的數(shù)據(jù)表格布局的輸出進行簡化。還提供多個機制,用于通過超級鏈接及其對選擇、排序、分頁和原地編輯和其它特性的支持,為輸出添加交互性。這使得該控件在若干的常見 Web 應(yīng)用方案中很有用,諸如列表、購物車和查詢結(jié)果。

DataGrid 還提供一些功能,這些功能具有 ASP+ 架構(gòu)所特有的所有服務(wù)器控件的特點。該控件包含進行與瀏覽器無關(guān)的輸出所需的邏輯,同時提供了一個統(tǒng)一的編程模型,從而能夠處理回傳數(shù)據(jù),以及對請求之間的狀態(tài)進行管理。這樣,開發(fā)商就可以針對帶有屬性、方法和事件的對象模型進行編程,而不必處理直接用 HTML 編程所帶來的不一致性和復(fù)雜性。

使用 ASP+ 列表綁定控件 介紹 DataGrid 控件以及相關(guān)的 DataList 和 Repeater 控件。還介紹了數(shù)據(jù)綁定、模板和格式化等等多個關(guān)鍵的概念。該文以此為基礎(chǔ)寫成,并將重點放在 DataGrid 控件,以揭示如何在您自己的應(yīng)用程序中利用該控件所提供的功能。



我們要建立什么?

該文舉出了一序列的示例頁面,彼此結(jié)合,從而最終生成一個頁面,該頁面以示例數(shù)據(jù)庫的 Authors 表和 Titles 表為依據(jù),提供主/詳細(xì)資料視圖(該數(shù)據(jù)庫隨 Microsoft SQL Server?2000 一起發(fā)運)。序列中的每個頁面均介紹 DataGrid 控件的一個新的特性或功能。下列圖象是從 pubs 數(shù)據(jù)庫抽取出來的。

主/詳細(xì)資料視圖類似于 Microsoft Access 所介紹的窗體/子窗體概念。也類似于隨 Microsoft Visual InterDev?6.0 一起發(fā)運的 DataForm Wizard (數(shù)據(jù)窗體向?qū)?#xff09;。主/詳細(xì)資料視圖顯示一到多的關(guān)系結(jié)果,其中視圖的一個部分顯示第一個查詢或主查詢的結(jié)果。然后跟蹤一個選擇,以篩選所使用的第二個查詢的結(jié)果,從而在視圖的另一部分顯示選擇內(nèi)容的詳細(xì)資料。

圖 1. 完成的頁面

圖 1 將 Author 列表顯示在頁面的上半部分,并將關(guān)于所選作者的詳細(xì)資料(包括相關(guān)書名)顯示在下半部分。 Authors 列表和 Titles 均是用 DataGrid 控件加以表示的。 顯示作者的 DataGrid 舉例說明如何進行選擇、排序、和分頁。顯示書名的 DataGrid 演示如何進行原地編輯、格式化和定制列。

數(shù)據(jù)訪問

為了使示例自成一體,從 SQL Server 抽取數(shù)據(jù)并將該數(shù)據(jù)連同其架構(gòu)信息一同保留為一個 XML 文件 TitlesDB.xml。下面是該文件的一個片斷。

<root>
<schema id="DocumentElement" targetNamespace=""xmlns="http://www.w3.org/1999/XMLSchema"xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"><element name="Author"><complexType content="elementOnly"><element name="au_id" type="string" minOccurs="1"maxOccurs="1"></element><element name="au_name" type="string" minOccurs="1"maxOccurs="1"></element><element name="address" type="string" minOccurs="0"maxOccurs="1"></element><element name="city" type="string" minOccurs="0"maxOccurs="1"></element><element name="state" type="string" minOccurs="0"maxOccurs="1"></element><element name="zip" type="string" minOccurs="0"maxOccurs="1"></element><element name="phone" type="string" minOccurs="0"maxOccurs="1"></element></complexType><unique name="AuthorConstraint" msdata:PrimaryKey="True"><selector>.</selector><field>au_id</field></unique></element><element name="Title"><complexType content="elementOnly"><element name="title_id" type="string" minOccurs="1"maxOccurs="1"></element><element name="au_id" type="string" minOccurs="1"maxOccurs="1"></element><element name="title" type="string" minOccurs="1"maxOccurs="1"></element><element name="price" msdata:DataType="System.Currency"type="string"minOccurs="1" maxOccurs="1"></element><element name="pubdate" type="timeInstant" minOccurs="1"maxOccurs="1"></element></complexType><unique name="TitleConstraint" msdata:PrimaryKey="True"><selector>.</selector><field>title_id</field></unique><key name="AuthorTitle"><selector>../Author</selector><field>au_id</field></key><keyref refer="AuthorTitle"><selector>.</selector><field>au_id</field></keyref></element>
</schema>
<DocumentElement><Author><au_id>154-00-1300</au_id><au_name>John Doe</au_name><phone>425 705 1234</phone><address>One Microsoft Way</address><city>Redmond</city><state>CA</state><zip>98005</zip></Author><Title><title_id>BU1032</title_id><au_id>213-46-8915</au_id><title>The Busy Executive's Database Guide</title><price>19.99</price><pubdate>1991-06-12T07:00:00</pubdate></Title>
</DocumentElement>
</root>

這些樣例簡化了數(shù)據(jù)訪問,從而將重點全部放在 DataGrid 的使用上。上面的 XML 被加載進一個 DataSetDataSet 為數(shù)據(jù)提供高速緩存,從而可以進行篩選、排序和編輯等等各種操作。下面的代碼來自 Global.asax,用于加載 DataSet 和將其保存為 Session 狀態(tài)。

public void Session_OnStart() {// 將樣例中所用的數(shù)據(jù)載入會話范圍的 DataSet.FileStream fs = null;DataSet ds = null;try {fs = new FileStream(Server.MapPath("Data//TitlesDB.xml"),FileMode.Open, FileAccess.Read);ds = new DataSet();ds.ReadXml(fs);} finally {if (fs != null) {fs.Close();fs = null;}}Session["AppData"] = ds;
}

在實際的 Web 應(yīng)用程序中,通常不是使用處于 SessionApplication 狀態(tài)的高速緩存數(shù)據(jù),而是通過所存儲的過程、中間層業(yè)務(wù)對象,或通過調(diào)用 Web 服務(wù)所揭示的方法來訪問和修改數(shù)據(jù)。無論采取怎樣的手段來訪問數(shù)據(jù),您會發(fā)現(xiàn)你依舊以同樣的方式來編程和與控件的對象模型進行進行交互。 www.IBuySpy.com (英文) 網(wǎng)站就是演示這些概念的一個很好的應(yīng)用示例。



第 1 步: 一個基本的 DataGrid

序列的第一步展示了一個頁面,其中包含單獨一個 DataGrid 控件,用于顯示來自數(shù)據(jù)源的一個只讀作者列表。結(jié)果類似于 使用 ASP+ 列表綁定控件 (英文) 所取得的效果。

圖 2. 完成第 1 步后的頁面

DataGrid 聲明來自:

Step1.aspx:

<asp:DataGrid id="authorsGrid" runat="server"AutoGenerateColumns="false"BackColor="White"BorderWidth="1px" BorderStyle="Solid" BorderColor="Tan"CellPadding="2" CellSpacing="0"Font-Name="Verdana" Font-Size="8pt"><property name="Columns"><asp:BoundColumn HeaderText="ID" DataField="au_id"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Name" DataField="au_name"><property name="HeaderStyle"><asp:TableItemStyle Width="150px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="State" DataField="state"><property name="HeaderStyle"><asp:TableItemStyle Width="50px"/></property></asp:BoundColumn></property><property name="HeaderStyle"><asp:TableItemStyle BackColor="DarkRed" ForeColor="White"Font-Bold="true"/></property><property name="ItemStyle"><asp:TableItemStyle ForeColor="DarkSlateBlue"/></property><property name="AlternatingItemstyle"><asp:TableItemStyle BackColor="Beige"/></property></asp:DataGrid>

上面的代碼展示 DataGrid,該控件的各種屬性已經(jīng)過聲明設(shè)定。 DataGrid 控件與其它 Web 控件如 FontBackColorForeColorBorderWidth 共享一組公用的樣式屬性。另外, DataGrid 提供僅適用于表的屬性如 CellPadding。最后, DataGrid 提供附加的樣式屬性,這些樣式屬性影響其中各項目和列如 HeaderStyleItemStyleAlternatingItemStyle 的表示。這些樣式屬性用于創(chuàng)建豐富多采且極富魅力的數(shù)據(jù)視覺效果。

DataGrid 支持從其所綁定的數(shù)據(jù)源自動生成列的功能。但是,在本例中, AutoGenerateColumns 屬性已被設(shè)定為 false。因此必須借助要展示的列集對 Columns 集合進行初始化。從而可以更多地控制表現(xiàn)效果,諸如列的次序和標(biāo)頭以及與每列對應(yīng)的樣式。這一步中所定義的列均為 BoundColumns,從而可以通過其 DataField 屬性,綁定到數(shù)據(jù)源的單獨一個字段。您在以后步驟中可以看到, DataGrid 允許選擇各種各樣類型的列。

下面的類包含支持本頁面的代碼。

Step1Page.cs:

namespace Samples {...public class Step1Page : Page {protected DataGrid authorsGrid;// 檢索存入會話狀態(tài)的應(yīng)用程序數(shù)據(jù)private DataSet GetSessionData() {return (DataSet)Session["AppData"];}// 檢索 Authors 表private ICollection GetAuthors() {DataSet ds = GetSessionData();DataView dv = ds.Tables["Author"].DefaultView;dv.RowFilter = String.Empty;return dv;}// 將 Authors 表載入 DataGridprivate void LoadAuthorsGrid() {ICollection authors = GetAuthors();authorsGrid.DataSource = authors;authorsGrid.DataBind();}// 超控 OnLoad,以在第一次請求過程中加載數(shù)據(jù)protected override void OnLoad(EventArgs e) {base.OnLoad(e);if (!IsPostBack) {LoadAuthorsGrid();}}}
}

該類超越 PageOnLoad 方法 (類似于實施 Page_Load),將 Author 列表作為 DataGrid 數(shù)據(jù)源進行加載。與其它服務(wù)器控件一樣, DataGrid 實施顯式的數(shù)據(jù)綁定模型,其中控件只在 DataBind 方法被調(diào)用時才列舉器數(shù)據(jù)源中的值。這樣設(shè)計各個控件,您就可以完全控制在哪個時間點需要數(shù)據(jù)源,并將無需數(shù)據(jù)時的數(shù)據(jù)訪問降至最低,例如大多數(shù)的往返過程。這一點會在將來的步驟中得到證明。

代碼還展示從 Session 狀態(tài)檢索的數(shù)據(jù),數(shù)據(jù)是在會話啟動過程中存為該狀態(tài)的。



第 2 步: 帶有多頁面的主/詳細(xì)資料視圖

創(chuàng)建主/詳細(xì)資料視圖的一個方法就是使用多頁面。在該方法中,主查詢中的選定值的詳細(xì)資料視圖被顯示在次要頁面上。在關(guān)于選定內(nèi)容的信息中,該次要頁面作為 URL 請求中的一個參數(shù)得到傳遞。

圖 3. 第 2 后的頁面,展示詳細(xì)資料頁面的浮動視圖

Step2.aspx 包含對 DataGrid 的更改,以使其包含一個名為 DataGrid 聲明的列。

Step2.aspx:

<asp:DataGrid id="authorsGrid" runat="server"AutoGenerateColumns="false"BackColor="White"BorderWidth="1px" BorderStyle="Solid" BorderColor="Tan"CellPadding="2" CellSpacing="0"Font-Name="Verdana" Font-Size="8pt"><property name="Columns"><asp:BoundColumn HeaderText="ID" DataField="au_id"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Name" DataField="au_name"><property name="HeaderStyle"><asp:TableItemStyle Width="150px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="State" DataField="state"><property name="HeaderStyle"><asp:TableItemStyle Width="50px"/></property></asp:BoundColumn>
   <asp:HyperLinkColumn Text="Details" DataNavigateUrlField="au_id"
        DataNavigateUrlFormatString="Step2a.aspx?AuthorID={0}"/></property><property name="HeaderStyle"><asp:TableItemStyle BackColor="DarkRed" ForeColor="White"Font-Bold="true"/></property><property name="ItemStyle"><asp:TableItemStyle ForeColor="DarkSlateBlue"/></property><property name="AlternatingItemstyle"><asp:TableItemStyle BackColor="Beige"/></property></asp:DataGrid>

DataGrid 聲明與第 1 步中的 DataGrid 聲明幾乎一樣。已將單獨一個 HyperLinkColumn 添加到 Columns 集合。 HyperLinkColumn 用來在 DataGrid 的每行中創(chuàng)建一個可導(dǎo)航的鏈接。該類型的列允許其 TextNavigateUrl 屬性與數(shù)據(jù)綁定。這樣, Text 屬性是靜態(tài)的,而 NavigateUrl 是數(shù)據(jù)綁定到作者 ID 的(通過設(shè)定 DataNavigateUrl 屬性)。另外,指定 DataNavigateUrlFormatString 建立一個以 Author ID 為參數(shù)的指向詳細(xì)資料頁面的 URL。 因此,每行均包含一個帶有“詳細(xì)資料”超級鏈接的附加列,而該鏈接的 URL 以與該行關(guān)聯(lián)的數(shù)據(jù)為依據(jù)。

HyperLinkColumn 代表著向本來只讀的數(shù)據(jù)顯示添加交互功能的第一步。

支持該頁面 (Step2Page.cs) 的代碼與第 1 步相同。添加這一列并不添加任何代碼,也不導(dǎo)致任何代碼發(fā)生變化,因此此處沒有列出那些代碼。

Step2a.aspx 實施詳細(xì)資料頁面,以顯示某一具體作者的詳細(xì)資料。

Step2a.aspx:

<asp:Panel id="detailsPanel" runat="server">
<table border="0" cellspacing="0" cellpadding="2" width="100%"style="font-family: verdana; font-size: 8pt"><tr><td width="200"><b>Name:</b></td><td width="100%"><%# DataBinder.Eval(CurrentAuthor, "au_name") %></td></tr><tr><td width="200"><b>ID:</b></td><td width="100%"><%# DataBinder.Eval(CurrentAuthor, "au_id") %></td></tr><tr><td width="200" valign="top"><b>Address:</b></td><td width="100%"><%# DataBinder.Eval(CurrentAuthor, "address") %><br><%# DataBinder.Eval(CurrentAuthor, "city") %>,<%# DataBinder.Eval(CurrentAuthor, "state") %><%# DataBinder.Eval(CurrentAuthor, "zip") %></td></tr><tr><td width="200"><b>Phone:<b></td><td width="100%"><%# DataBinder.Eval(CurrentAuthor, "phone") %></td></tr><tr><td colspan="2"><b>Title(s) Authored</b></td></tr><tr><td colspan="2"><asp:DataGrid id="titlesGrid" runat="server"DataSource='<%# DataBinder.Eval(CurrentAuthor, "AuthorTitle") %>'AutoGenerateColumns="false"ShowFooter="true"BackColor="White"BorderWidth="1px" BorderStyle="Solid" BorderColor="Tan"CellPadding="2" CellSpacing="0"Font-Name="Verdana" Font-Size="8pt"OnItemCreated="OnItemCreatedTitlesGrid"><property name="Columns"><asp:BoundColumn HeaderText="ID" DataField="title_id"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Title" DataField="title"><property name="HeaderStyle"><asp:TableItemStyle Width="250px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Published" DataField="pubdate"DataFormatString="{0:MMM yyyy}"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Price" DataField="price"DataFormatString="{0:c}"><property name="HeaderStyle"><asp:TableItemStyle Width="50px"/></property><property name="ItemStyle"><asp:TableItemStyle HorizontalAlign="Right"/></property></asp:BoundColumn></property><property name="HeaderStyle"><asp:TableItemStyle BackColor="DarkRed" ForeColor="White"Font-Bold="true"/></property><property name="FooterStyle"><asp:TableItemStyle BackColor="Tan"/></property><property name="ItemStyle"><asp:TableItemStyle ForeColor="DarkSlateBlue"/></property><property name="AlternatingItemstyle"><asp:TableItemStyle BackColor="Beige"/></property></asp:DataGrid></td></tr>
</table>
</asp:Panel>

本頁包含若干使用 DataBinder.Eval 的數(shù)據(jù)綁定表達式。這些表達式抽取本頁代碼中所實施的 CurrentAuthor 屬性的各個屬性。

DataGrid 用于顯示選定作者所編著的書名。與第 1 步相同, DataGrid 包含一個針對要顯示的列的定義,以及用于為列、行和總體控制提供可視格式化的樣式屬性設(shè)置。

BoundColumns 還允許對數(shù)據(jù)進行格式化。正如在上面聲明中看到的那樣, DataFormatString 屬性用于對日期和貨幣值進行格式化。格式化對于表示本地化文字和控制非字符串類型的文字呈現(xiàn)來講極其有用。

Step2aPage.cs 包含支持詳細(xì)資料頁面的代碼。

Step2aPage.cs:

namespace Samples {...public class Step2aPage : Page {private object currentAuthor;// 返回當(dāng)前選定的 Author public object CurrentAuthor {get {return currentAuthor;}}// 檢索存入會話狀態(tài)的應(yīng)用程序數(shù)據(jù)private DataSet GetSessionData() {return (DataSet)Session["AppData"];}// 處理 ItemCreated 事件,以將標(biāo)尾定制為// 顯示總結(jié)信息protected void OnItemCreatedTitlesGrid(object sender,DataGridItemCreatedEventArgs e) {if (e.Item.ItemType == ListItemType.Footer) {int cellCount = e.Item.Cells.Count;for (int i = 0; i < cellCount - 1; i++) {e.Item.Cells.RemoveAt(0);}int itemCount = titlesGrid.Items.Count;string itemCountString;if (itemCount == 0) {itemCountString = "No Titles Found";}else {itemCountString = Int32.ToString(itemCount) +" title(s)";}TableCell summaryCell = e.Item.Cells[0];summaryCell.Text = itemCountString;summaryCell.ColumnSpan = cellCount;summaryCell.HorizontalAlign = HorizontalAlign.Right;}}// 超控 OnLoad,以載入選定作者的詳細(xì)資料protected override void OnLoad(EventArgs e) {base.OnLoad(e);string authorID = Request.QueryString["AuthorID"];if (authorID != null) {SelectAuthor(authorID);detailsPanel.DataBind();}}// 根據(jù)給定作者 ID 來設(shè)置 CurrentAuthor 對象private void SelectAuthor(string authorID) {DataSet ds = GetSessionData();DataView dv = ds.Tables["Author"].DefaultView;dv.RowFilter = "au_id = '" + authorID + "'";currentAuthor = dv[0];}}
}

通過訪問 Request.QueryString 集合,類就超越頁面的 OnLoad 方法來檢索作為 URL 請求中的參數(shù)傳來的 Author ID。然后使用該 Author ID 來查詢數(shù)據(jù)源和設(shè)置 CurrentAuthor 屬性。最后,調(diào)用 DataBind,從而為所有的數(shù)據(jù)綁定的表達式求值。

另外,該頁面為 DataGrid 控件的 ItemCreated 事件實施了一個事件處理器。 ItemCreated 事件是 DataGrid 為其高級用途提供的擴展機制之一。該事件允許從行的控件結(jié)構(gòu)內(nèi)部添加和刪除控件,以及在特殊情況下將其添加到特定行。

DataGrid 每次創(chuàng)建一個項目(或行)時,就引發(fā)該事件。這具體有兩種情況:

  • 要對控件進行數(shù)據(jù)綁定,且項目需要從頭創(chuàng)建,則在將項目進行數(shù)據(jù)綁定之前,引發(fā)該事件。

  • 當(dāng)要從往返過程中的保存狀態(tài)創(chuàng)建項目時,則在將所保存的狀態(tài)載入項目及其包含的控件之前引發(fā)該事件。

結(jié)果是,該事件提供一個掛鉤,用于對項目的現(xiàn)有控件結(jié)構(gòu)進行更改。

在本例中,處理器修改控件的標(biāo)尾,以顯示所列書名的的一個計數(shù)。標(biāo)尾所包含的列的數(shù)目與其它行一樣。摘要需要橫跨整個 DataGrid。因此,處理器僅保留行中的一個單元格,將其余全部刪除,并將僅剩的單元格的 ColumnSpan 重置,以使其橫跨整個列集,設(shè)定其 HorizontalAlign 屬性,以使文字右對齊,最后設(shè)定其 Text,指示計數(shù)。

處理該事件時,只有一條規(guī)則需要遵守:您必須進行同樣的結(jié)構(gòu)轉(zhuǎn)換,無論調(diào)用該項目的上下文如何,無論是在數(shù)據(jù)綁定過程中,還是在往返過程中。



第 3 步: 單頁面中的主/詳細(xì)資料視圖

創(chuàng)建主/詳細(xì)資料視圖的另一備選且更常用的方法就是用單頁面顯示這些視圖。

圖 4. 完成第 3 步后的頁面

Authors DataGrid 來自:

Step3.aspx:

<asp:DataGrid id="authorsGrid" runat="server"...
    DataKeyField="au_id"
    OnSelectedIndexChanged="OnSelIndexChangedAuthorsGrid"><property name="Columns">
    <asp:ButtonColumn Text="Select" Command="Select"/>...</property>...    <property name="SelectedItemStyle">
    <asp:TableItemStyle BackColor="PaleGoldenRod" Font-Bold="true"/>
  </property>
</asp:DataGrid> 

與前一步相比,該聲明中有三處變化。

首先,在第 2 步中添加的 HyperLinkColumn 已被刪除。這不再需要,因為整個視圖是在單頁面中實施的。

其次,向列集添加了一個新的列類型 ButtonColumn。該列在每行中生成 LinkButton,用于提交該頁,而不是從該頁進行瀏覽。列的 Command 屬性設(shè)定為 Select,對相應(yīng)的 LinkButton 屬性進行設(shè)定。 DataGrid 將 Select 作為一個標(biāo)準(zhǔn)命令,將包含被單擊按鈕的列選定。

當(dāng)選定內(nèi)容發(fā)生變化時, DataGrid 就引發(fā) SelectedIndexChanged 事件,該事件在代碼中得到處理。 DataKeyField 屬性頁得到設(shè)定,從而導(dǎo)致 DataKeys 集合填置與數(shù)據(jù)源中的每個項目相對應(yīng)的值。

該頁面還包含針對題為 detailsPanel 的面板內(nèi)的詳細(xì)資料節(jié)的 UI 和布局。這是從第 2 步原樣復(fù)制的。

Step3Page.cs 表示這一步中的 .aspx 頁面的支持代碼。其中包括來自第 2 步中兩個有代碼支持的文件的代碼組合。來自詳細(xì)資料頁面的大部分代碼均為原樣照搬。下面顯示的代碼包含我們所作的更改和補充。

Step3Page.cs:

namespace Samples {...public class Step3Page : Page {private object currentAuthor;// 將 Authors 表載入 DataGrid// 另外還更新選定的作者private void LoadAuthorsGrid() {ICollection authors = GetAuthors();authorsGrid.DataSource = authors;if (authors.Count != 0) {authorsGrid.SelectedIndex = 0;}else {authorsGrid.SelectedIndex = -1;}authorsGrid.DataBind();
            UpdateDetails();}// 處理作者網(wǎng)格中的 SelectedIndexChanged 事件,以// 更新詳細(xì)資料protected void OnSelIndexChangedAuthorsGrid(object sender,EventArgs e) {UpdateDetails();}// 根據(jù)當(dāng)前選定的作者來更新// 詳細(xì)資料節(jié)private void UpdateDetails() {
            UpdateSelection();            if (currentAuthor != null) {
                detailsPanel.Visible = true;
                detailsPanel.DataBind();
            }
            else {
                detailsPanel.Visible = false;
            }
        }        // 更新當(dāng)前選定的作者
        private void UpdateSelection() {
            int selectedIndex = authorsGrid.SelectedIndex;            currentAuthor = null;
            if (selectedIndex != -1) {
                string authorID =
                       (string)authorsGrid.DataKeys[selectedIndex];                DataSet ds = GetSessionData();
                DataView dv = ds.Tables["Author"].DefaultView;                dv.RowFilter = "au_id = '" + authorID + "'";
                currentAuthor = dv[0];
            }
        }}
}

每次加載 Authors DataGrid 時,就初始化其 SelectedIndex 屬性。一旦得到綁定,即其 DataKeys 集合填置完畢,就通過調(diào)用 UpdateDetails,更新詳細(xì)資料節(jié)。

針對 SelectedIndexChanged 事件的處理器中的詳細(xì)資料節(jié)也得到更新。注意,此時已借助 DataBind 未被調(diào)用以來的保存狀態(tài)將 DataKeys 集合填置完畢。

UpdateDetails 方法首先調(diào)用 UpdateSelectionUpdateSelection 使用 Authors DataGrid 的 SelectedIndexDataKeys 屬性來確定選定作者的 ID 和初始化 CurrentAuthor 屬性。然后, UpdateDetails 調(diào)用 detailsPanel 控件上的 DataBind,對訪問 CurrentAuthor 的數(shù)據(jù)綁定表達式進行求值。

除了借助 SelectedIndexChanged 事件進行選擇跟蹤,還可以從本樣例實現(xiàn)另一關(guān)鍵概念。注意,改變選擇內(nèi)容并不需要已將 Authors DataGrid 進行過數(shù)據(jù)綁定。因此,從不需要重新加載 Authors 列表,從而極大地減少了對 Authors 表的訪問。這是 ASP+ 中所實施的顯式數(shù)據(jù)綁定模型的一個關(guān)鍵益處。



第 4 步: 排序

DataGrid 支持生成可點擊標(biāo)頭的功能,此類標(biāo)頭可以用于讓最終用戶對控件中所展示的數(shù)據(jù)進行排序。這一步添加了對 Authors 列表進行排序的功能。

圖 5. 完成第 4 步后頁面的屏幕快照

Authors DataGrid 來自:

Step4.aspx

<asp:DataGrid id="authorsGrid" runat="server"...
    AllowSorting="true"
    OnSortCommand="OnSortCommandAuthorsGrid"
    OnItemCreated="OnItemCreatedAuthorsGrid"><property name="Columns"><asp:ButtonColumn Text="Select" Command="Select"/><asp:BoundColumn HeaderText="ID" DataField="au_id"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn>
    <asp:BoundColumn HeaderText="Name" DataField="au_name"
        SortField="au_name"><property name="HeaderStyle"><asp:TableItemStyle Width="150px"/></property></asp:BoundColumn>
    <asp:BoundColumn HeaderText="State" DataField="state"
        SortField="state"><property name="HeaderStyle"><asp:TableItemStyle Width="75px"/></property></asp:BoundColumn></property>...
</asp:DataGrid>

通過將 AllowSorting 設(shè)定為 true,啟用排序。然后,對不支持排序的每列的 SortField 屬性進行設(shè)定。沒有設(shè)定該屬性的列不會生成可點擊標(biāo)頭。最后,處理 SortCommand 事件,這會在有代碼支持的文件的上下文中加以論述。樣例還為 ItemCreated 事件添加了一個事件處理器,以在視覺上顯示列標(biāo)頭中的當(dāng)前排序設(shè)置。下面的代碼展示為向 Authors 列表添加排序功能而在有代碼支持的類中進行更改和補充。

Step4Page.cs:

namespace Samples {...public class Step4Page : Page {        // 返回當(dāng)前的排序方向,該信息是在
        // Page 狀態(tài)中維持的
        protected bool SortAscending {
            get {
                object o = State["SortAscending"];
                if (o != null)
                    return (bool)o;
                return true;
            }
            set {
                State["SortAscending"] = value;
            }
        }        // 返回當(dāng)前的排序字段,該信息是在
        // Page 狀態(tài)中維持的
        protected string SortField {
            get {
                object o = State["SortField"];
                if (o != null)
                    return (string)o;
                return "au_name";
            }
            set {
                State["SortField"] = value;
            }
        }// 檢索 Authors 表private ICollection GetAuthors() {DataSet ds = GetSessionData();DataView dv = ds.Tables["Author"].DefaultView;dv.RowFilter = String.Empty;            string sort = SortField;
            if (SortAscending == false) {
                sort += " desc";
            }
            dv.Sort = sort;return dv;}        // 處理 ItemCreated 事件,以用排序圖符對標(biāo)頭
        // 進行定制
        protected void OnItemCreatedAuthorsGrid(object sender,
                                   DataGridItemCreatedEventArgs e) {
            if (e.Item.ItemType == ListItemType.Header) {
                string sortField = SortField;
                bool ascending = SortAscending;                Label sortGlyph = new Label();
                sortGlyph.Text = ascending ? " 5" : " 6";
                sortGlyph.Font.Name = "Webdings";                TableCell cell = null;
                if (sortField.Equals("au_name")) {
                    cell = e.Item.Cells[2];
                }
                else if (sortField.Equals("state")) {
                    cell = e.Item.Cells[3];
                }                if (cell != null) {
                    cell.Controls.Add(sortGlyph);
                }
            }
        }        // 處理作者網(wǎng)格中的 SortCommand 事件,以更新
        // 排序參數(shù)和重新加載新排序的數(shù)據(jù)
        protected void OnSortCommandAuthorsGrid(object sender,
                                    DataGridSortCommandEventArgs e) {
            string currentSortField = SortField;            SortField = e.SortField;
            if (currentSortField.Equals(e.SortField)) {
                SortAscending = !SortAscending;
            }
            else {
                SortAscending = true;
            }            LoadAuthorsGrid();
        }}
}

頁面將當(dāng)前字段和排序方向作為名值對,保留在頁面的 State 屬性中,并將其作為 SortFieldSortAscending 屬性提供出來,此時,頁面負(fù)責(zé)在往返過程之間維持這些屬性的值。

這些屬性用于 GetAuthors 函數(shù),這里,在返回 Author 列表 之前,會根據(jù)屬性的當(dāng)前值對其進行排序。

用于 SortCommand 事件的事件處理器在 DataGridSortCommandEventArgs 的一個實例中得到傳遞。該對象包含 SortField 屬性的值,而該屬性與標(biāo)題被單擊的列相關(guān)聯(lián)。您可以選擇對該值進行任意處理,只要該處理在您的應(yīng)用程序中合理。例如,該值可以包含單個字段的名稱,例如本樣例中的情形,也可以包含排序信息,從而允許進行多列排序。

實施該方法,對 SortFieldSortAscending 屬性的值進行更新。最后,該方法調(diào)用 LoadAuthorsGrid,對 Authors DataGrid 進行數(shù)據(jù)綁定。此時情況是, DataGrid 的列需要重新生成,要求您設(shè)定數(shù)據(jù)源和調(diào)用 DataBind

ItemCreated 的事件處理器類似于第 2 步中用于 Titles DataGrid 的事件處理器。此時,處理器修改標(biāo)頭行的控件結(jié)構(gòu),具體方法是添加表示上升和下降的圖符,指示當(dāng)前已排序的列和當(dāng)前的排序方向。

這里有一個問題需要回答,DataGrid 為何不對其數(shù)據(jù)進行實際的排序。這主要有兩個原因。首先, ASP+ 的數(shù)據(jù)源是一般的 ICollection,以便您在選擇數(shù)據(jù)源時擁有最大的靈活性。數(shù)據(jù)源并不包含內(nèi)置的排序語義。其次,也是更重要的一點, 在每次請求過程中,自動排序均會需要數(shù)據(jù)源的一個活動的實例。這不太適合用于顯式數(shù)據(jù)綁定結(jié)構(gòu)中,因為這需要您在頁面的往返過程中訪問和加載數(shù)據(jù)。



第 5 步: 分頁

DataGrid 提供顯示特殊行的功能,該行包含用于顯示頁碼和“下一步”/“上一步”瀏覽按鈕的 UI。這一步添加了對 Authors 列表進行分頁查看的功能。

圖 6. 完成第 5 步后頁面的屏幕快照

Authors DataGrid 來自:

Step5.aspx:

<asp:DataGrid id="authorsGrid" runat="server"...
    AllowPaging="true" PageSize="5"
    OnPageIndexChanged="OnPageIndexChangedAuthorsGrid">...  <property name="PagerStyle">
    <asp:DataGridPagerStyle BackColor="Tan" HorizontalAlign="Right"
        PageButtonCount="3" Mode="NumericPages"/>
  </property>
</asp:DataGrid>

與排序類似,您必須設(shè)定幾個屬性并實施一個事件處理器,從而啟用分頁功能。啟用分頁功能的具體步驟是,將 AllowPaging 屬性設(shè)定為 true,并將 PageSize 屬性設(shè)定為一個正整數(shù)。 PageSize 屬性確定了要在單頁面中表現(xiàn)的數(shù)據(jù)源的值。

該樣例還展示設(shè)定 PagerStyle 屬性,從而使您可以對分頁 UI 的視覺外觀和布局進行定制。樣例將分頁器一次展示三個頁碼按鈕,方法是將 Mode 設(shè)定為 NumericButtons,而將 PageButtonCount 屬性設(shè)定為 "3",并使其向右對其。除了這些設(shè)置,您還可以選擇“下一步”/“上一步”樣式按鈕,分頁 UI 的位置,其顏色方案,等等。

要支持分頁,就必須對 DataGrid 的 PageIndexChanged 事件進行處理,具體討論見 Step5Page.cs。

Step5Page.cs:

namespace Samples {...public class Step5Page : Page {        // 處理作者網(wǎng)格中的 PageIndexChanged 事件,以
        // 更新數(shù)據(jù)
        protected void OnPageIndexChangedAuthorsGrid(object sender,
                                  DataGridPageChangedEventArgs e) {
            LoadAuthorsGrid();
        }}
}

PageIndexChangedEvent 的事件處理程序只是重新加載 DataGrid,從而自動呈現(xiàn)數(shù)據(jù)源中所有項目的分頁視圖。事件處理器是在 DataGridPageChangedEventArgs 的一個實例中傳遞的,該實例包含關(guān)于舊的頁面索引和新的頁面索引的信息。如果根據(jù)應(yīng)用程序的狀態(tài),您確定不應(yīng)更改頁面索引,則可以僅將 DataGrid 的 CurrentPageIndex 屬性設(shè)定回舊的頁面索引,跳過重新加載數(shù)據(jù)。顯式數(shù)據(jù)綁定模型使這成為可能。這里,直到對 DataBind 進行調(diào)用時 DataGrid 的內(nèi)容才得到刷新。

DataGrid 支持一種備選的分頁模式,您可以通過將 AllowCustomPaging 屬性設(shè)定為 true 而啟用該模式。在該模式中,您負(fù)責(zé)向 DataGrid 告知您的數(shù)據(jù)源中的值的總數(shù),具體方法是設(shè)定 VirtualItemCount 屬性。一旦處于該模式,您的數(shù)據(jù)源就想必只包含當(dāng)前頁面的值。在該模式中,僅需從查詢檢索最少數(shù)目的值,從而進一步優(yōu)化您的數(shù)據(jù)訪問。



第 6 步: 原地編輯

DataGrid 支持對其行的原地編輯。這一步使用該功能,從而允許在 Titles DataGrid 內(nèi)部進行編輯。

圖 7. 完成第 6 步后的頁面

Titles DataGrid 來自:

Step6.aspx:

<asp:DataGrid id="titlesGrid" runat="server"...
    OnEditCommand="OnEditCommandTitlesGrid"
    OnUpdateCommand="OnUpdateCommandTitlesGrid"
    OnCancelCommand="OnCancelCommandTitlesGrid"><property name="Columns">
    <asp:BoundColumn HeaderText="ID" DataField="title_id" ReadOnly="true"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn>
    <asp:BoundColumn HeaderText="Title" DataField="title" ReadOnly="true"><property name="HeaderStyle"><asp:TableItemStyle Width="250px"/></property></asp:BoundColumn>
    <asp:BoundColumn HeaderText="Published" DataField="pubdate"
        DataFormatString="{0:MMM yyyy}" ReadOnly="true"><property name="HeaderStyle"><asp:TableItemStyle Width="100px"/></property></asp:BoundColumn><asp:BoundColumn HeaderText="Price" DataField="price"DataFormatString="{0:c}"><property name="HeaderStyle"><asp:TableItemStyle Width="50px"/></property><property name="ItemStyle"><asp:TableItemStyle HorizontalAlign="Right"/></property></asp:BoundColumn>
     <asp:EditCommandColumn EditText="Edit" CancelText="Cancel"
          UpdateText="OK"/></property>...
</asp:DataGrid>

通過處理控件的 EditCommandUpdateCommandCancelCommand 事件來達到在 DataGrid 內(nèi)進行編輯的目的。

Columns 集合包含一個名為 EditCommandColumn 的新的列。該列自動創(chuàng)建每行右側(cè)的按鈕集。為只讀模式中的各行創(chuàng)建 Edit 按鈕,并為編輯模式中的各行創(chuàng)建 UpdateCancel 按鈕。列的 EditTextCancelTextUpdateText 屬性用來指定按鈕的文本。注意,也可以將文本設(shè)定為 HTML 標(biāo)記,從而為這些按鈕使用圖象。

最后,各種列的 ReadOnly<./font> 屬性被設(shè)定為 true。這就防止對這些列中的數(shù)據(jù)進行編輯,即使列處于編輯模式。對于本樣例,只有價格字段是可編輯的,因而所有其它 BoundColumns 均被標(biāo)注為只讀。

上面聲明的事件處理器在下面展示的有代碼支持的類中得到實施。

Step6Page.cs:

namespace Samples {...public class Step6Page : Page {// 更新當(dāng)前選定的作者并重新加載與選定內(nèi)容對應(yīng)的書名// 網(wǎng)格protected void LoadTitlesGrid() {UpdateSelection();titlesGrid.DataBind();}// 處理書名網(wǎng)格中的 CancelCommand 事件,以// 不施用更改就結(jié)束編輯protected void OnCancelCommandTitlesGrid(object sender,DataGridCommandEventArgs e) {titlesGrid.EditItemIndex = -1;LoadTitlesGrid();}// 處理書名網(wǎng)格中的 EditCommand 事件,以// 開始編輯某一行protected void OnEditCommandTitlesGrid(object sender,DataGridCommandEventArgs e) {titlesGrid.EditItemIndex = e.Item.ItemIndex;LoadTitlesGrid();}// 處理書名網(wǎng)格中的 UpdateCommand 事件,以施用// 所作的更改并結(jié)束編輯protected void OnUpdateCommandTitlesGrid(object sender,DataGridCommandEventArgs e) {TextBox priceText =(TextBox)e.Item.FindControl("Column3Control");string newPrice = priceText.Text.Substring(1);DataSet ds = GetSessionData();DataTable titlesTable = ds.Tables["Title"];string titleID =(string)titlesGrid.DataKeys[e.Item.ItemIndex];DataRow[] rows = titlesTable.Select("title_id = '" +titleID + "'");DataRow editRow = rows[0];editRow.BeginEdit();editRow["price"] = newPrice;editRow.EndEdit();editRow.AcceptChanges();titlesGrid.EditItemIndex = -1;LoadTitlesGrid();}}
}

EditCommand 事件是在單擊 Edit 按鈕時引發(fā)的。只需將 DataGrid 的 EditItemIndex 屬性設(shè)定為包含被單擊按鈕的項目的索引的屬性。要防止編輯某一個別行,不采取任何動作就返回。另外,要繼續(xù)進行編輯,就必須重新加載數(shù)據(jù)源并調(diào)用 DataBind。這通過調(diào)用 LoadTitlesGrid 方法來完成。

您必須處理的第二個事件就是 CancelCommand 事件。這是單擊 Cancel 按鈕時引發(fā)的。實施十分類似于前一處理器。如想結(jié)束編輯,則只需將 EditItemIndex 屬性重置為 ?,并重新加載數(shù)據(jù)源。如果需要維持行的編輯模式,則僅需不采取任何動作就從函數(shù)返回即可。

要處理的最后一個事件就是 UpdateCommand 事件,這是單擊 Update 按鈕時引發(fā)的。這里是實際工作發(fā)生的地方。從存在于項目中的控件抽取新的值,然后更新數(shù)據(jù)源。一旦將新的值使用完畢,就將 EditItemIndex 重置為 ?,以返回到只讀模式,并連同其數(shù)據(jù)源一起重新加載控件。對于前兩個事件,您可以不采取任何動作就從該函數(shù)返回,以保持該行的編輯模式狀態(tài)。

這一步又再次舉例說明控件中實施的顯式數(shù)據(jù)綁定模型。在這一實施情形中,只在某行的狀態(tài)從只讀模式更改為編輯模式或相反時才需要數(shù)據(jù)源。注意, DataGrid 自身并不更新其數(shù)據(jù)源。實質(zhì)上,數(shù)據(jù)綁定是單向的。采用本模型的目的在于讓您擁有對數(shù)據(jù)源更新的控制。在大多數(shù)典型的應(yīng)用程序中,更新需要預(yù)處理,并且是由業(yè)務(wù)對象或已存儲的過程來調(diào)用的。另外,單向數(shù)據(jù)綁定并不要求每個時間都有實時的數(shù)據(jù)源。



第 7 步: 使用模板

DataGrid 控件通過使用 TemplateColumns,支持列內(nèi)模板。可以完全自由地決定與這些列相關(guān)聯(lián)的單元格的內(nèi)容。這一步使用 TemplateColumn 來增強首先在前一步中實施的編輯支持。

圖 8. 完成第 7 步后的頁面

Titles DataGrid 來自:

Step7.aspx:

<asp:DataGrid id="titlesGrid" runat="server"...><property name="Columns">...
    <asp:TemplateColumn HeaderText="Price">
      <template name="ItemTemplate">
        <asp:Label runat="server"
            Text='<%# DataBinder.Eval(Container.DataItem, "price",
                                      "{0:c}") %>'/>
      </template><template name="EditItemTemplate"><asp:RequiredFieldValidator runat="server"ControlToValidate="priceText" Display="Dynamic"><img src="Error.gif" height="16" width="16" title="Required"align="absmiddle"></asp:RequiredFieldValidator><asp:RegularExpressionValidator runat="server"ControlToValidate="priceText" Display="Dynamic"ValidationExpression="/$[0-9]+(/.[0-9][0-9]?)?"><img src="Error.gif" height="16" width="16"title="Invalid currency value"align="absmiddle"></asp:RegularExpressionValidator><asp:TextBox id="priceText" runat="server"Text='<%# DataBinder.Eval(Container.DataItem, "price","{0:c}") %>'Width="45px" BorderStyle="Solid" BorderWidth="1px"BorderColor="Black"></asp:TextBox></template><property name="HeaderStyle"><asp:TableItemStyle Width="50px"/></property><property name="ItemStyle"><asp:TableItemStyle HorizontalAlign="Right"/></property></asp:TemplateColumn></property>...
</asp:DataGrid>

控件的聲明展示將 TemplateColumn 添加到 Columns 集合,以替代價格字段的 BoundColumnTemplateColumns 是 DataGrid 的另一擴展機制。可以將其用于對 DataGrid 所創(chuàng)建的表格式布局內(nèi)所表現(xiàn)的 UI 進行完全定制。 TemplateColumn 還提供模板屬性,比如 ItemTemplateEditItemTemplate,從而您可以指定應(yīng)當(dāng)用于與列相關(guān)聯(lián)的單元格內(nèi)的控件。

在本例中, ItemTemplate 包含一個 Label 控件,其 Text 屬性綁定到價格字段。這實質(zhì)上在模仿 BoundColumn 的功能。

有意思的是, EditItemTemplate 模板用于處于編輯模式中的單元格。樣例將一個 TextBox 放入已綁定到價格字段的模板中。這樣就提供了與 BoundColumn 相同的功能。

模板包含各種各樣的增強性能。首先,該模板允許對 TextBox 進行更大的控制,從而您可以創(chuàng)建在視覺上更有魅力的編輯 UI。其次,允許您放置驗證控件,從而可以進行原地驗證。在本樣例中, RequiredFieldValidator 確保 TextBox 總是包含一個值,而 RegularExpressionValidator 確保文本包含一個有效的貨幣值。該功能的最令人興奮的一個方面就是自動進行客戶機端驗證。 ASP+ 驗證控件自動進行客戶機端驗證,并開啟功能豐富的瀏覽器客戶機上的錯誤指示器,從而無須往返過程和回落到為下級客戶機進行服務(wù)器端驗證。

Step7Page.cs:

namespace Samples {...public class Step7Page : Page {// 處理書名網(wǎng)格中的 UpdateCommand 事件,以施用// 所作的更改并結(jié)束編輯 (當(dāng)頁面處于有效狀態(tài)時)protected void OnUpdateCommandTitlesGrid(object sender,DataGridCommandEventArgs e) {
            if (IsValid) {TextBox priceText =(TextBox)e.Item.FindControl("priceText");string newPrice = priceText.Text.Substring(1);DataSet ds = GetSessionData();DataTable titlesTable = ds.Tables["Title"];string titleID =(string)titlesGrid.DataKeys[e.Item.ItemIndex];DataRow[] rows = titlesTable.Select("title_id = '" +titleID + "'");DataRow editRow = rows[0];editRow.BeginEdit();editRow["price"] = newPrice;editRow.EndEdit();editRow.AcceptChanges();titlesGrid.EditItemIndex = -1;LoadTitlesGrid();}}}
}

對支持代碼的唯一變更與繼續(xù)對數(shù)據(jù)源進行更新之前檢查頁面的有效性有關(guān)。驗證控件會自動更新頁面的 IsValid 屬性。

檢查有效性是在 UpdateCommand 事件處理器中完成的。如第 6 步中所述,不采取任何動作就從事件處理器返回,會保持行的編輯模式。因此,當(dāng),且僅當(dāng)頁面處于有效狀態(tài)時,才會執(zhí)行所有的更新邏輯。

證實控件還會在無效時自動顯示其錯誤消息,且無需編寫任何補充代碼。



第 8 步: 定制列

正如到目前您所看到的, DataGrid 控件支持標(biāo)準(zhǔn)的列集,諸如 BoundColumnButtonColumnTemplateColumn。該控件還允許您用自己的列類型對控件進行擴展。這些新的列提供了高度的靈活性。這一步實施一個名為 ImageColumn 的定制列,該列用于在單元格中,為帶有圖象 URL 數(shù)據(jù)綁定的每行顯示一個圖象。

圖 9. 完成第 8 步后的頁面

Titles DataGrid 以及 ImageColumn 的聲明來自:

Step8.aspx:Step8.aspx:

<%@ Register TagPrefix="s" Namespace="Samples"%>
...
<asp:DataGrid id="titlesGrid" runat="server"...><property name="Columns">
    <s:ImageColumn ImageField="title_id"
       ImageFormatString="images/Title-{0}.gif"/></property>...
</asp:DataGrid>

本頁面包含一個寄存器指令,用于映射 <s:ImageColumn> 標(biāo)記,以表示 Samples.ImageColumn 類。

DataGrid 的聲明展示添加到 DataGrid 的 Columns 集合的 ImageColumn。 還展示 ImageFieldImageFormatString 集,因而圖象是以包含與特定行相關(guān)聯(lián)的標(biāo)題 ID 的 URL 為依據(jù)的。其工作原理與第 2 步中所使用的 HyperLinkColumn 十分類似。

ImageColumn.cs:

namespace Samples {...public class ImageColumn : Column {private PropertyDescriptor imageFieldDesc;public ImageColumn() {}public string ImageField {get {object o = State["ImageField"];return (o != null) ? (string)o : String.Empty;}set {State["ImageField"] = value;}}public string ImageFormatString {get {object o = State["ImageFormatString"];return (o != null) ? (string)o : String.Empty;}set {State["ImageFormatString"] = value;}}// 在與該列相關(guān)聯(lián)的單元格中創(chuàng)建// 控件public override void InitializeCell(TableCell cell,int columnIndex,ListItemType itemType) {base.InitializeCell(cell, columnIndex, itemType);if ((itemType == ListItemType.Item) ||(itemType == ListItemType.AlternatingItem) ||(itemType == ListItemType.SelectedItem) ||(itemType == ListItemType.EditItem)) {Image image = new Image();image.ID = Column.GetColumnControlID(columnIndex, -1);cell.Controls.Add(image);if (ImageField.Length != 0) {image.AddOnDataBind(newEventHandler(this.OnDataBindColumn));}}}// 將數(shù)據(jù)載入在 InitializeCell 中創(chuàng)建的控件private void OnDataBindColumn(object sender, EventArgs e) {Image boundImage = (Image)sender;DataGridItem item = (DataGridItem)boundImage.NamingContainer;object dataItem = item.DataItem;if (IsFirstDataBind()) {string imageField = ImageField;imageFieldDesc =TypeDescriptor.GetProperties(dataItem)[imageField];if (imageFieldDesc == null) {throw new Exception("Invalid property: '" +imageField + "'");}OnFirstDataBindHandled();}object data = imageFieldDesc.GetValue(dataItem);if (data != null) {string format = ImageFormatString;if (format.Length != 0) {boundImage.ImageUrl = String.Format(format, data);}else {boundImage.ImageUrl = data.ToString();}}}}
}

DataGrid 控件所使用的每一列均由抽象的 Column 類派生而來。 列類型實施各種各樣的屬性 (諸如 HeaderText) 以及所有列類型所公用的樣式。

ImageColumn 類用于添加針對其具體功能的屬性,諸如 ImageFieldImageFormatString 屬性。實施這些屬性,是通過將各值存入列的 State 中實現(xiàn)的。列的狀態(tài),在 DataGrid 控件的往返過程中自動得到保持。

每列所超控的最為重要的虛擬方法就是 InitializeCell 方法。 DataGrid 促使每列初始化與該列相關(guān)聯(lián)的單元格。實施本方法時,列創(chuàng)建其所需要的控件,并將它們添加為單元格的子單元格。所創(chuàng)建的控件可能會隨 itemType 參數(shù)的不同而不同,該參數(shù)指示包含單元格的列的 ItemType 屬性。 Column 類自身包含用于產(chǎn)生標(biāo)頭和標(biāo)尾的邏輯。 ImageColumn 在進行自我實施時,只是創(chuàng)建一個 Image 控件。它還向 Image 的 DataBind 屬性添加一個事件處理器。

一旦將列創(chuàng)建完畢, DataGrid 就對其進行數(shù)據(jù)綁定。在該進程中,允許列借助與列相關(guān)聯(lián)的數(shù)據(jù)對其在 InitializeCell 中創(chuàng)建的控件進行定制。 ImageColumn 檢索其所綁定的字段的值,使用用戶所指定的格式生成一個 URL,然后使用結(jié)果字符串來設(shè)定圖象的 ImageUrl 屬性。



結(jié)論

DataGrid 控件簡化了多個常見 Web 應(yīng)用情形,其中包括只讀報表到交互式應(yīng)用程序 UI。該控件優(yōu)于傳統(tǒng)的 ASP 編程。它將轉(zhuǎn)換對象模型操作和數(shù)據(jù)綁定所需的邏輯封裝進與瀏覽器無關(guān)的 HTML 表現(xiàn)功能。還將處理回傳數(shù)據(jù)以及轉(zhuǎn)換客戶機事件的詳細(xì)資料封狀進服務(wù)器事件。

該控件設(shè)計用于無須作出太多開發(fā)努力就可以表現(xiàn)您的數(shù)據(jù)。隨著應(yīng)用要求的改變,以及您開始使用 DataGrid 的各種功能,您可以逐步添加其它功能。

現(xiàn)在 Microsoft??.NET SDK 和 Framework 中就已提供該控件。 SDK 還包含補充文檔和多個樣例,可用于快速啟動;兩者均實施本文中所提供的材料。

總結(jié)

以上是生活随笔為你收集整理的使用 ASP+ DataGrid 控件来创建主视图/详细资料视图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。