使用asp+ 列表綁定控件
nikhil kothari
microsoft corporation
2000年7月
摘要: 說明asp+ repeater、datalist 和datagrid 服務器控件。這些控件能夠實現一個根植於數據源的,基於html 的應用程序用戶界面。討論與這些控件有關的概念並概要介紹使用這些控件的基本示例。
目錄
簡介
列表綁定控件是如何工作的?
repeater 控件
datalist 控件
datagrid 控件
repeater、datalist 或datagrid?
相關資源
下載與本文相關的示例文件(56 kb)。
簡介
repeater、datalist 和datagrid 控件構成asp+ 頁面框架中system.web.ui.webcontrols 名稱空間內的相關web 控件集。這些控件使html 顯示所綁定列表或數據源的內容。因此,將它們統稱為“列表綁定控件”。
與框架中的其它web 控件類似,這些控件提供一致的編程模型並封裝一個獨立於瀏覽器的表示邏輯。這些特性使開發人員能夠針對對像模型編程而不用必須掌握與html 相關的那些不一致的和復雜的技術知識。
這三種控件可以按多種佈局(包括列表、分欄/報紙欄目和流佈局(html 流))來表示與其相關的數據源內容。此外,它們還允許您創建完全不同的或完全定制的佈局。除了封裝有表示邏輯外,還提供了用來處理已發送數據、執行狀態管理和引發事件的功能。最後,它們還對諸如選擇、編輯、分頁和排序之類的標準操作提供不同級別的支持。這些控件可以簡化幾種常見的web 應用程序方案,包括報表、購物車、產品列表、查詢結果和導航菜單。
下面幾節將進一步說明這些控件和如何在您的web 應用程序中使用它們,以及如何選用控件。
列表綁定控件是如何工作的?
本節是本文其餘部分的背景材料。概述了這些列表綁定控件的工作方式、它們的共同特性以及某些相關概念。
datasource 屬性
每個控件都有一個datasource 屬性,其類型為system.collections.icollection。用最簡單的話來說,數據源是同類對象的一個列表或集合。
此框架中有幾個對象提供了icollection 的實現。這個集合包括system.data.dataview (它通常用來訪問關係數據庫和xml 數據)、一般icollection 實現(如arraylist 和hashtable)以及數組。
與傳統的數據綁定控件(它們通常需要ado 記錄集)不同,除了實現icollection 接口之外,這些列表綁定控件未對其數據源強加任何其它要求。根據設計,通過大量增加可作為有效datasource 屬性值的類型和數據結構,它們能夠為您的應用程序代碼實現最大程度的簡單和靈活性。
項目集合
每個列表綁定控件都包含一個項目集合。控件通過列舉這些對象當前的數據源來置入其項目集合。在列舉中為每個對象創建單個項目並用於表示該對象。這些項目同時成為列表綁定控件中包含的控件層次結構的一部分。
下表列出了與數據源的數據相關聯的項目類型。
項目創建的默認項目類型
alternatingitem 為項目集合中具有奇數下標的項目創建
selecteditem 為選定的項目創建(不論該項目是否為備選項目)
edititem 為處於編輯模式下的項目創建(不管它是否被選中或是否為備選項目)
控件同時創建將在表示中用到的下列項目。但是,它們並不與數據源的數據相關聯。
標頭用來表示標頭信息
註腳用來表示註腳信息
分隔符用來表示圖1 中所示的每個項目之間的內容,並且僅適用於repeater 和datalist
分頁符用來表示與datagrid 控件相關聯的分頁ui
圖1. 相對於“控件”集合的“項目”集合
項目的數據綁定和創建
列表綁定控件遵循在整個asp+ 框架中實現的顯式數據綁定模型。這意味著控件僅當其databind 方法被調用時才需要並列舉其數據源。
當調用databind 方法時,列表控件將列舉其數據源、創建項目並通過從其數據源中提取值來對其進行初始化。如果啟用了狀態管理,則控件還將保存所需的全部信息,以便在頁面的回傳處理期間重新創建其項目而無須重新設置數據源。
顯式數據綁定模型使您的應用程序代碼可以精確地確定在處理序列中何時及何處需要數據源。這種功能使對數據庫服務器的訪問更少且更高效,而這些訪問通常是web 應用程序最耗費資源的操作。
一般規則是每當您需要重新創建項目時都必須調用databind。在大多數情況下,您將在您的頁面首次被請求創建初始項目集合時調用databind。在該頁面的後續執行過程中,您將需要在引起項目集合被更改的各種事件處理程序中調用此方法。當用於創建初始數據源的查詢被修改時,就可能發生這種情況。當項目的狀態改變(如從只讀模式變為編輯模式)時也可能發生這種情況。
樣式
通過在對像模型上使用樣式屬性,您可以定義全部datalist 和datagrid 控件及其所包含項目的格式和外觀。這些屬性允許定製字體、顏色、邊框和其它外觀因素。控件本身的樣式屬性(如前景色、背景色、字體和邊框樣式)將影響整個控件的表示。
此外,每個控件都包含與其所創建的項目類型相匹配的大量樣式屬性,如as itemstyle、alternatingitemstyle 和headerstyle。 datagrid 提供第三級的樣式屬性,這些屬性將影響特定列的所有單元格。控件中包含的每一列都可以擁有其自己的headerstyle、footerstyle 和itemstyle。
模板
樣式控制格式顯示,而模板則定義每個項目的內容和表示。您可以將模板看作html 代碼片斷,它定義了用來表示項目的控件層次結構。
repeater 和datalist 控件由您指定的模板來驅動,提供各種可設置的模板屬性,如itemtemplate、alternatingitemtemplate 和headertemplate。與樣式類似,每個模板都對應於一個特定類型的項目。
datagrid 控件未模板化。但是,控件的column 集合中的templatecolumns 使datagrid 中模板的使用成為可能。 templatecolumn 中的每個單元格都可以包含一個模板,這與repeater 或datalist 控件中的項目極為類似。這也使datagrid 中的定製表示成為可能。
模板中的數據綁定
模板定義項目中包含的控件層次結構。通過使用數據綁定表達式,此層次結構中的控件屬性可綁定到與此項目相關聯的數據屬性上。
作為模板的邏輯父級的項目在數據綁定表達式中被稱為“容器”。每個容器都有一個稱為dataitem 的屬性,該屬性引用其相關聯的數據。結果是,模板中的大多數典型數據綁定表達式都將控件屬性綁定到container.dataitem 的某個屬性上。將在以下幾節介紹的示例中進一步說明這種綁定。
repeater 控件
如前面所述,repeater 控件是完全由模板驅動的,允許創建完全可定制的表示和佈局。下圖說明了這一功能。
圖2. 使用repeater 控件生成的帶項目符號的鏈接列表
摘自repeater1.aspx:
<%@ page language=c# src=repeater1.cs inherits=samples.repeater1page%>
...
<asp:repeater runat=server id=linkslistrepeater
datasource='<%# sitelinks %>'>
<template name=headertemplate>
<ul type=1>
</template>
<template name=itemtemplate>
<li>
<asp:hyperlink runat=server
text='<%# databinder.eval(container.dataitem, sitename) %>'
navigateurl='<%# databinder.eval(container.dataitem, siteurl) %>'>
</asp:hyperlink>
</li>
</template>
<template name=footertemplate>
</ul>
</template>
</asp:repeater>
此.aspx 文件顯示了一個用於生成帶項目符號列表的repeater 控件的聲明。
此示例說明了用數據綁定語法(<%#...%>) 設置數據源的聲明方法。當您調用databind 方法時,數據綁定中的表達式就會被執行。在這種情況下,repeater 的datasource 屬性被綁定到頁面的sitelinks 屬性上,後者包含要顯示的url 引用。
repeater 是唯一允許在其模板中存在html 片段的控件,將repeater 控件和html 片段合在一起會產生良好形式的html。在本示例中,帶項目符號的列表分為三個部分:
由headertemplate 表示的列表開始標記(<ul type=1>)。
由footertemplate 表示的列表結束標記(</ul>)。
列表的主體由通過為sitelinks 集合中出現的每個對象重複itemtemplate 而生成的列表項(<li>) 置入。
您也可以使用這些模板在標頭中指定表的開始標記(<table>),在註腳中指定表的結束標記(</table>),在每個項目中指定單個表行(<tr>) 。此替換選項將導致列表表示。
您必須指定itemtemplate。它是唯一必需的模板。當未指定其它模板時,控件會自動將此itemtemplate 用於其它模板。
在以下示例中,itemtemplate 包含一個hyperlink web 控件。此控件的text 和navigateurl 屬性被綁定到與每個重複項目相關聯的數據屬性上。這又是使用數據綁定表達式(在創建項目後立即對該表達式求值)完成的。
repeater1.cs:
namespace samples {
...
public class repeater1page : page {
protected repeater linkslistrepeater;
public icollection sitelinks {
get {
arraylist sites = new arraylist();
sites.add(new siteinfo(microsoft home,
http://www.microsoft.com));
sites.add(new siteinfo(msdn home,
http://msdn.microsoft.com));
sites.add(new siteinfo(msn homepage,
http://www.msn.com));
sites.add(new siteinfo(hotmail,
http://www.hotmail.com));
return sites;
}
}
protected override void onload(eventargs e) {
base.onload(e);
if (!ispostback) {
// 首次請求該頁時即對其進行數據綁定(databind)。
// 這將在此頁的控件層次結構中遞歸調用每個控件。
databind();
}
}
}
public sealed class siteinfo {
private string sitename;
private string siteurl;
public siteinfo(string sitename, string siteurl) {
this.sitename = sitename;
this.siteurl = siteurl;
}
public string sitename {
get { return sitename; }
}
public string siteurl {
get { return siteurl; }
}
}
}
此.cs 文件包含隨前一個列表中的aspx 頁一起出現的代碼。
repeater1page 類覆蓋了page 類的onload 方法。此表示在對該頁的首次請求中調用databind。這將導致對這些頁上的數據綁定表達式求值並使repeater 控件列舉數據源以及創建其項目。僅在首次請求時調用databind 方法。這之所以能正常工作是因為repeater 能夠在從前一次保存狀態的回傳過程中重新創建其項目,而無需數據源實例。
此頁將類型icollection 的公用屬性顯露出來。這將在設置repeater 的datasource 屬性值的數據綁定表達式中使用。屬性的獲取實現使用包含一組siteinfo 對象序列的arraylist。此屬性是公用的,因為只有頁類的公用和保護成員可在數據綁定表達式中使用。
每個siteinfo 對像有兩個屬性:sitename 和siteurl。當對模板中的hyperlink 控件進行數據綁定時將訪問這些屬性。在此控件的綁定表達式中,container.dataitem 表示要將特定項綁定到其上的單個siteinfo 對象。 databinder.eval(container.dataitem, sitename) 訪問當前siteinfo 對象的sitename 屬性。
repeater1 示例向您介紹了幾個基本概念:
定義模板
模板中的數據綁定語法和數據綁定表達式
將arraylist 的icollection 表示用作數據源
在最初處理頁的過程中調用databind 方法
datalist 控件
datalist 控件是一個模板化控件,它提供使用樣式屬性可視化地格式化其表示的能力。它也可以產生多列佈局。圖3 說明了這兩種特性。
圖3. 從datalist 的雙列表示生成的示例
摘自datalist1.aspx:
<%@ page language=c# src=datalist1.cs inherits=samples.datalist1page%>
...
<asp:datalist runat=server id=peopledatalist
repeatcolumns=2 repeatdirection=vertical repeatmode=table
width=100%>
<property name=alternatingitemstyle>
<asp:tableitemstyle backcolor=#eeeeee/>
</property>
<template name=itemtemplate>
<asp:panel runat=server font-size=12pt font-bold=true>
<%# ((person)container.dataitem).name %>
</asp:panel>
<asp:label runat=server width=20px
borderstyle=solid borderwidth=1px bordercolor=black
backcolor='<%# ((person)container.dataitem).favoritecolor %>'>
</asp:label>
<asp:label runat=server font-size=10pt
text='<%# getcolorname(((person)container.dataitem).favoritecolor) %>'>
</asp:label>
</template>
</asp:datalist>
此.aspx 文件顯示了用來生成此示例的datalist 的聲明。
在此示例中,datalist 的多列佈局是通過將repeatcolumns 屬性設置為“2”來實現的。將repeatdirection 設置為“vertical”會使項目從上到下、然後從左到右排列。相反,值設置為“horizontal”會導致項目從左到右、然後從上到下排列。
aspx 語法包含對少數幾種datalist 的樣式屬性的設置。在此示例中,datalist 的width 被設置為其父級的100%。設置具有灰色背景的alternatingitemstyle 是為了獲得帶有條紋的外觀。此示例還說明模板可以包含任意複雜的控件定義,以滿足在每個項目內獲得理想佈局的需要。
最後,此模板中的數據綁定表達式通過將container.dataitem 轉換為其類型來使用前期綁定。這不會招致與使用databinder.eval (如repeater1 中所示) 相關聯的後期綁定的代價。但是,這種方法可能會產生可讀性較差的表達式。以下示例還給出了一個調用getcolorname 方法(該方法是在本頁有代碼支持的文件中實現的)的表達式示例。
datalist1.cs:
namespace samples {
...
public class datalist1page : page {
protected datalist peopledatalist;
protected string getcolorname(color c) {
return
typedescriptor.getconverter(typeof(color)).converttostring(c);
}
private void loadpeoplelist() {
// 創建數據源
person[] people = new person[] {
new person(nikhil kothari, color.green),
new person(steve millet, color.purple),
new person(chris anderson, color.blue),
new person(mike pope, color.orange),
new person(anthony moore, color.yellow),
new person(jon jung, color.mediumaquamarine),
new person(susan warren, color.slateblue),
new person(izzy gryko, color.red)
};
// 設置控件的數據源
peopledatalist.datasource = people;
// 並使該控件用此數據源構建其項目
peopledatalist.databind();
}
protected override void onload(eventargs e) {
base.onload(e);
if (!ispostback) {
// 首次請求此頁
loadpeoplelist();
}
}
}
public sealed class person {
private string name;
private color favoritecolor;
public person(string name, color favoritecolor) {
this.name = name;
this.favoritecolor = favoritecolor;
}
public color favoritecolor {
get { return favoritecolor; }
}
public string name {
get { return name; }
}
}
}
在此頁中,控件的datasource 屬性是通過程序設置的,與在aspx 文件中聲明性地設置相對。兩種方法的結果相同。無法選擇哪種方法,都必須調用databind 方法,以便控件可以列舉其數據源並創建它要表示的項目。
此示例中所用的數據源是person 對象的一個簡單數組。由於每個數組都實現icollection 方法,所以數組適合用作數據源。這顯示了將數據結構和類型用作數據源時可獲得的靈活程度。
datalist1 示例介紹了下列概念:
在模板中定義豐富的html ui
使用簡單數組作為數據源
通過程序設置數據源
數據綁定語法中所允許的各種表達式