DataGrid 控件 DataGrid 控件使您可以生成數(shù)據(jù)源格式豐富的列表表示。此外,它還支持隨其它操作選擇項(xiàng)目。
本節(jié)的四個(gè)示例使用包含有關(guān)書(shū)名信息(標(biāo)題、標(biāo)題 ID、作者、價(jià)格和出版日期)的表。全部數(shù)據(jù)都用 TitlesDB.xml 中的 XML 予以維持。在建立頁(yè)面來(lái)表示此表的內(nèi)容并選擇書(shū)籍時(shí),這些示例遵循增量方法。代碼列表包含黑體文本,以表明一個(gè)示例構(gòu)建于以前示例時(shí)所作的更改。
截自 TitlesDB.xml:
<root> <schema id="DocumentElement" targetNamespace="" xmlns=http://www.w3.org/1999/XMLSchema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <element name="Title"> <complexType content="elementOnly"> <element name="title_id" type="string"></element> <element name="title" type="string"></element> <element name="au_name" type="string"></element> <element name="price" msdata:DataType="System.Currency" minOccurs="0" type="string"></element> <element name="pubdate" type="timeInstant"></element> </complexType> <unique name="TitleConstraint" msdata:PrimaryKey="True"> <selector>.</selector> <field>title_id</field> </unique> </element> </schema> <DocumentElement> <Title> <title_id>BU1032</title_id> <title>The Busy Executive's Database Guide</title> <au_name>Marjorie Green</au_name> <price>19.99</price> <pubdate>1991-06-12T07:00:00</pubdate> </Title> ... </DocumentElement> </root>
在典型的 Web 應(yīng)用程序中,為了獲得最大的可伸縮性和性能上的好處,很可能會(huì)使用 Web 服務(wù)或商業(yè)對(duì)象來(lái)存取數(shù)據(jù)。為了簡(jiǎn)化這些示例并將注意力集中在使用 DataGrid 而不是數(shù)據(jù)存取上,我們選擇在應(yīng)用程序啟動(dòng)時(shí)一次性加載數(shù)據(jù),并在 Global.asax 中的 ASP 應(yīng)用程序狀態(tài)中高速緩存所得的 DataSet,如下所示。
截自 Global.asax:
public void Application_OnStart() { FileStream fs = null; DataSet ds = null;
try { fs = new FileStream(Server.MapPath("TitlesDB.xml"), FileMode.Open, FileAccess.Read); ds = new DataSet();
// 將 xml 文件中的數(shù)據(jù)加載到 DataSet 中 ds.ReadXml(fs); } finally { if (fs != null) { fs.Close(); fs = null; } }
// 將數(shù)據(jù)集高速緩存到應(yīng)用程序狀態(tài)中,以便在單個(gè)頁(yè)面中使用 Application["TitlesDataSet"] = ds; }
DataGrid1 DataGrid1 說(shuō)明 DataGrid 的基本用法,說(shuō)明控件如何用最少的用戶(hù)代碼生成表示來(lái)提供豐富的功能。
圖 4. 通過(guò)使用具有自動(dòng)生成列的 DataGrid 產(chǎn)生的示例
截自 DataGrid1.aspx:
<%@ Page language="C#" src="DataGrid.cs" inherits="Samples.DataGridPage"%> ...
<asp:DataGrid runat=server id="titlesGrid"> </asp:DataGrid>
上面的 .aspx 文件顯示在不設(shè)置 DataGrid 控件任何屬性的情況下對(duì)其進(jìn)行聲明。
DataGrid.cs:
namespace Samples { ...
public class DataGridPage : Page { protected DataGrid titlesGrid;
public ICollection GetTitlesList() { // 從在應(yīng)用程序狀態(tài)中高速緩存的 DataSet 中檢索標(biāo)題列表。 DataSet titlesDataSet = (DataSet)Application["TitlesDataSet"];
if (titlesDataSet != null) { return titlesDataSet.Tables["Title"].DefaultView; } else { return null; } }
private void LoadTitlesGrid() { // 從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù) ICollection titlesList = GetTitlesList();
// 設(shè)置控件的數(shù)據(jù)源 titlesGrid.DataSource = titlesList;
// 并使它用此數(shù)據(jù)源構(gòu)建其項(xiàng)目 titlesGrid.DataBind(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e);
if (!IsPostBack) { // 首次請(qǐng)求此頁(yè) LoadTitlesGrid(); } } } }
.cs 文件包含用于此頁(yè)的代碼。此代碼與 DataList1 示例中使用的代碼功能相同。在對(duì)此頁(yè)的首次請(qǐng)求中,它覆蓋 OnLoad 方法以檢索數(shù)據(jù)并在調(diào)用 DataBind 之前設(shè)置控件的 DataSource 屬性。這將使 DataGrid 創(chuàng)建其項(xiàng)目,這些項(xiàng)目是表中必要的行。在回傳處理的過(guò)程中,DataGrid 從狀態(tài)(該狀態(tài)包括在上一次請(qǐng)求中所保存的單元格內(nèi)容)重新創(chuàng)建項(xiàng)目。
此示例說(shuō)明了 DataGrid 控件的 AutoGenerateColumns 屬性的功能。此屬性的默認(rèn)值為 true。當(dāng)設(shè)置為 true 時(shí),DataGrid 將使用 reflection 檢查其數(shù)據(jù)源和對(duì)象,并為每個(gè)公用屬性或字段創(chuàng)建一個(gè)列。在此示例中,控件表示“標(biāo)題”表中當(dāng)前的所有字段。這一功能允許用最少的用戶(hù)代碼快速而容易地生成任何數(shù)據(jù)源的列表表示。
每個(gè)自動(dòng)生成列的類(lèi)型都是 BoundColumn。這種列類(lèi)型將與其關(guān)聯(lián)的屬性值轉(zhuǎn)換為要用作窗體元格文本的字符串。
DataGrid2 DataGrid2 說(shuō)明具有在 .aspx 文件中定義的 Columns 集合的 DataGrid。
圖 5. 通過(guò)使用具有指定列的 DataGrid 產(chǎn)生的示例
摘自 DataGrid2.aspx:
<%@ Page language="C#" src="DataGrid.cs" inherits="Samples.DataGridPage"%> ...
<asp:DataGrid runat=server id="titlesGrid" AutoGenerateColumns="false"> <property name="Columns"> <asp:BoundColumn headerText="Title" DataField="title"/> <asp:BoundColumn headerText="Author" DataField="au_name"/> <asp:BoundColumn headerText="Date Published" DataField="pubdate"/> <asp:BoundColumn headerText="Price" DataField="price"/> </property> </asp:DataGrid>
此 .aspx 文件顯示了一個(gè)具有用戶(hù)指定的列集合的 DataGrid 控件。此示例使用與 DataGrid1 相同的有代碼支持的文件,因?yàn)椴恍枰娜魏未a。
DataGrid 的 AutoGenerateColumns 屬性被設(shè)置為假,從而阻止控件自動(dòng)生成列,而讓用戶(hù)負(fù)責(zé)定義將要在表中表示的列。
有許多好處:
您可控制列的順序。以聲明的順序表示列。另一方面,自動(dòng)生成的列是按用映像檢索到的順序表示的,此順序不必與代碼中的列順序或數(shù)據(jù)庫(kù)表本身的列順序相匹配。
可以用列的 headerText 屬性來(lái)指定每列的標(biāo)頭。在前一個(gè)示例中,列標(biāo)頭指明了字段名,這可能并不合適。當(dāng)在此模式下使用控件時(shí),Columns 還提供其它可設(shè)置的屬性。
自動(dòng)生成的列的類(lèi)型始終是 BoundColumn。指定列集合使用戶(hù)可以控制每列的類(lèi)型。 DataGrid3 DataGrid3 通過(guò)添加可視格式化和內(nèi)容格式化構(gòu)建于 DataGrid2 之上。
圖 6. 由設(shè)置了樣式和格式化屬性的 DataGrid 產(chǎn)生的示例
摘自 DataGrid3.aspx:
<%@ Page language="C#" src="DataGrid.cs" inherits="Samples.DataGridPage"%> ...
<asp:DataGrid runat=server id="titlesGrid" AutoGenerateColumns="false" Width="80%" BackColor="White" BorderWidth="1px" BorderStyle="Solid" CellPadding="2" CellSpacing="0" BorderColor="Tan" Font-Name="宋體" Font-Size="8pt"> <property name="Columns"> <asp:BoundColumn headerText="Title" DataField="title"/> <asp:BoundColumn headerText="Author" DataField="au_name"/> <asp:BoundColumn headerText="Date Published" DataField="pubdate" DataFormatString="{0:MMM yyyy}"/> <asp:BoundColumn headerText="Price" DataField="price" DataFormatString="{0:c}"> <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="ItemStyle"> <asp:TableItemStyle ForeColor="DarkSlateBlue"/> </property> <property name="AlternatingItemStyle"> <asp:TableItemStyle BackColor="Beige"/> </property> </asp:DataGrid>
此 .aspx 文件顯示了與前面相同的 DataGrid 控件聲明,并設(shè)置了各種樣式屬性。這將導(dǎo)致視覺(jué)上更具吸引力的表示。仍就不需要對(duì)代碼進(jìn)行任何更改,使用與以前示例相同的有代碼支持的文件。
因?yàn)樗菑?WebControl 得到的,所以 DataGrid 控件繼承了諸如 Width、BackColor、BorderStyle 和 Font.Name 之類(lèi)的樣式屬性。此外,DataGrid 提供諸如 CellPadding 這樣的屬性,這些屬性是特定于表的。這些屬性允許從總體上定制控件。
聲明還顯示了設(shè)置的若干項(xiàng)目樣式,如 headerStyle 和 AlternatingItemStyle。這些樣式控制著它們相應(yīng)項(xiàng)目的外觀(guān)。請(qǐng)注意此示例中出現(xiàn)的樣式合并。備選項(xiàng)目與一般項(xiàng)目的前景色相同,因?yàn)樗鼈兊臉邮绞?AlternatingItemStyle 和 ItemStyle 的組合。最后,此示例還通過(guò)右對(duì)齊價(jià)格列中的文本說(shuō)明了為特定列設(shè)置樣式。
DataGrid 還允許您格式化其單元格中的文本內(nèi)容。這是通過(guò)設(shè)置 BoundColumn 的 DataFormatString 屬性值完成的。該列使用其格式說(shuō)明格式化使用 String.Format 的單元格內(nèi)容。此屬性可隨格式化類(lèi)型(如日期或貨幣)一起預(yù)置或附加任意內(nèi)容。此外,由于格式化考慮了當(dāng)前頁(yè)的 CultureInfo 和請(qǐng)求,所以它也支持全局化。如果未指定格式,則使用該值的 ToString 方法。
DataGrid4 DataGrid4 說(shuō)明如何通過(guò)處理 SelectedIndexChanged 事件來(lái)利用 DataGrid 中的選擇。
圖 7. 由允許選擇其包含項(xiàng)目的 DataGrid 產(chǎn)生的示例
截自 DataGrid4.aspx:
<%@ Page language="C#" src="DataGrid4.cs" inherits="Samples.DataGrid4Page"%> ...
<asp:DataGrid runat=server id="titlesGrid" AutoGenerateColumns="false" Width="80%" BackColor="White" BorderWidth="1px" BorderStyle="Solid" CellPadding="2" CellSpacing="0" BorderColor="Tan" Font-Name="宋體" Font-Size="8pt" DataKeyField="title_id" OnSelectedIndexChanged="OnSelectedIndexChangedTitlesGrid"> <property name="Columns"> <asp:ButtonColumn Text="Select" Command="Select"/> <asp:BoundColumn headerText="Title" DataField="title"/> <asp:BoundColumn headerText="Author" DataField="au_name"/> <asp:BoundColumn headerText="Date Published" DataField="pubdate" DataFormatString="{0:MMM yyyy}"/> <asp:BoundColumn headerText="Price" DataField="price" DataFormatString="{0:c}"> <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="ItemStyle"> <asp:TableItemStyle ForeColor="DarkSlateBlue"/> </property> <property name="AlternatingItemStyle"> <asp:TableItemStyle BackColor="Beige"/> </property> <property name="SelectedItemStyle"> <asp:TableItemStyle BackColor="PaleGoldenRod" Font-Bold="true"/> </property> </asp:DataGrid> ... <asp:Label runat=server id="selectionInfoLabel" Font-Name="宋體" Font-Size="8pt"/> 在此 .aspx 文件中,為 DataGrid 的 SelectedIndexChanged 事件注冊(cè)了一個(gè)事件處理程序。此事件處理程序是在有代碼支持的文件中實(shí)現(xiàn)的。已在列集合中添加了一個(gè)命令 為“Select”的 ButtonColumn,使得 DataGrid 為每個(gè)項(xiàng)目表示一個(gè)包含 Select 按鈕的附加列。同時(shí)指定了 SelectedItemStyle。此樣式用于從視覺(jué)上區(qū)分選定的項(xiàng)目。最后還指定了 DataGrid 的 DataKeyField 屬性。此字段將置入 DataGrid 的 DataKeys 集合,該集合將在有代碼支持的文件中用到。
DataGrid4.cs:
namespace Samples { ...
public class DataGrid4Page : Page { protected DataGrid titlesGrid; protected Label selectionInfoLabel;
public ICollection GetTitlesList() { // 從在應(yīng)用程序狀態(tài)中高速緩存的 DataSet 中檢索標(biāo)題列表。 DataSet titlesDataSet = (DataSet)Application["TitlesDataSet"];
if (titlesDataSet != null) { return titlesDataSet.Tables["Title"].DefaultView; } else { return null; } }
private void LoadTitlesGrid() { // 從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù) ICollection titlesList = GetTitlesList();
// 設(shè)置控件的數(shù)據(jù)源并重新設(shè)置其選擇, titlesGrid.DataSource = titlesList; titlesGrid.SelectedIndex = -1;
// 并使該控件使用此數(shù)據(jù)源構(gòu)建其項(xiàng)目 titlesGrid.DataBind();
// 更新選定的標(biāo)題信息 UpdateSelectedTitleInfo(); }
protected override void OnLoad(EventArgs e) { base.OnLoad(e);
if (!IsPostBack) { // 首次請(qǐng)求此頁(yè) LoadTitlesGrid(); } }
// 處理 DataGrid 的 OnSelectedIndexChanged 事件 protected void OnSelectedIndexChangedTitlesGrid(object sender, EventArgs e) { UpdateSelectedTitleInfo(); }
private void UpdateSelectedTitleInfo() { // 獲取選定的索引 int selIndex = titlesGrid.SelectedIndex; string selTitleID = null; string selectionInfo;
if (selIndex != -1) { // 顯示選定標(biāo)題的關(guān)鍵字段 selTitleID = (string)titlesGrid.DataKeys[selIndex]; selectionInfo = "ID of selected title: " + selTitleID; } else { selectionInfo = "No title is currently selected."; }
selectionInfoLabel.Text = selectionInfo; } } }
此 .cs 文件包含處理 SelectedIndexChanged 事件以及在 DataGrid 下顯示選定標(biāo)題的 ID 的邏輯。DataGrid 處理命令事件,該事件是通過(guò)包含在其項(xiàng)目中的按鈕觸發(fā)的。它識(shí)別標(biāo)準(zhǔn)命令“Select”,該命令使其更改它的 SelectedIndex 屬性,并通過(guò)觸發(fā)此事件來(lái)將此更改通知用戶(hù)的代碼。
在實(shí)現(xiàn)事件處理程序的過(guò)程中,示例代碼調(diào)用 UpdateSelectedTitleInfo 方法。該方法負(fù)責(zé)顯示有關(guān)選定書(shū)名的信息,本例中為標(biāo)題的 ID。在更現(xiàn)實(shí)的方案中,此 ID 可用來(lái)鏈接某個(gè)頁(yè)面,以顯示有關(guān)選定標(biāo)題的更多詳細(xì)信息。
ID 是通過(guò)訪(fǎng)問(wèn) DataKeys 集合進(jìn)行檢索的。該集合是因?yàn)樵O(shè)置了 DataKeyField 屬性而置入的。通常,將它設(shè)置為主關(guān)鍵字或使用戶(hù)可以唯一標(biāo)識(shí)項(xiàng)目的某些其它字段,并將此信息用作后續(xù)的數(shù)據(jù)庫(kù)查詢(xún)或過(guò)濾數(shù)據(jù)中的準(zhǔn)則。
此示例說(shuō)明除了僅僅表示數(shù)據(jù)源中的對(duì)象之外,如何進(jìn)一步支持諸如選擇數(shù)據(jù)源中對(duì)象之類(lèi)的操作。DataGrid 包含對(duì)若干其它特性(如排序、分頁(yè)、現(xiàn)場(chǎng)編輯和 TemplateColumns)的支持。但是,這些特定特性超出了本文的討論范圍,將在以后的文章中加以探討。
Repeater、DataList 或 DataGrid? Repeater、DataList 和 DataGrid 控件共享公用編程模型。同時(shí),每個(gè)控件都被設(shè)計(jì)為側(cè)重某個(gè)特定方案,為正確的方案選擇正確的列表綁定控件是一個(gè)重要的決策。本節(jié)說(shuō)明控件層次結(jié)構(gòu)和每種控件的功能,以及每種控件可能用于的典型方案的示例。
正如在下面的類(lèi)層次結(jié)構(gòu)中看到的那樣,Repeater 是一種小巧輕便的控件。它只繼承了基本Control類(lèi)的功能,如 ID 屬性和子控件集合。另一方面,DataList 控件和 DataGrid 控件都繼承了 WebControl 功能,如樣式和外觀(guān)屬性。
圖 8. 列表綁定控件的類(lèi)層次結(jié)構(gòu)
在對(duì)象模型方面,repeater 控件是最簡(jiǎn)單的控件。它同時(shí)也是最小的數(shù)據(jù)綁定控件并且基本上是不同的,即它不會(huì)強(qiáng)制使用任何特殊的 UI 布局。最后的表示遵循生成文本的方法,其方式是通過(guò)重復(fù)為此控件指定的模板內(nèi)容。此控件對(duì)樣式和外觀(guān)屬性或行為不提供任何內(nèi)建的支持。對(duì)于需要完全控制表示的方案而言,它是一個(gè)極好的選擇。
DataList 控件是強(qiáng)制使用分列布局或流布局的 repeater。它繼承了 WebControl 中實(shí)現(xiàn)的外觀(guān)屬性,并增加了適用于它所創(chuàng)建的項(xiàng)目的其它樣式屬性。DataList 控件還包括對(duì)其項(xiàng)目標(biāo)準(zhǔn)操作(如選擇、編輯和刪除)的支持。它很適用于生成分布于一列或多列的水平或垂直的項(xiàng)目序列流。
DataGrid 控件強(qiáng)制使用列或行的列表布局。與 DataList 類(lèi)似,此控件提供樣式和外觀(guān)屬性。除選擇和編輯之外,DataGrid 還支持對(duì)整個(gè)項(xiàng)目集合的高級(jí)操作,如分頁(yè)和排序。DataGrid 和 DataList 的一個(gè)主要區(qū)別是 DataGrid 不包含任何模板屬性,即 DataGrid 控件的項(xiàng)目或行是非模板化的。但是,將 TemplateColumn 添加到 DataGrid 中就可以在特定列中使用模板。
下表是列表綁定控件所提供的功能的摘要。
功能 Repeater DataList DataGrid 模板 是(必需) 是(必需) 列內(nèi)(可選) 列表布局 否 否 是 流布局 是 是 否 分列/報(bào)紙欄目樣式布局 否 是 否 樣式和外觀(guān)屬性 否 是 是 選擇 否 是 是 編輯 否 是 是 刪除 否 是 是 分頁(yè) 否 否 是 排序 否 否 是
相關(guān)資源 隨 Microsoft .NET Framework SDK 發(fā)布的 QuickStart 示例包含這些控件的若干示例,以及說(shuō)明使用 XML 和 Web 服務(wù)存取數(shù)據(jù)的示例。SDK 附帶的文檔包括相關(guān)主題的概念性資料,如 ASP+ 頁(yè)面框架和服務(wù)器控件,以及說(shuō)明作為此框架一部分的控件的對(duì)象模型的參考書(shū)目。
|
溫馨提示:喜歡本站的話(huà),請(qǐng)收藏一下本站!