使用 ObjectList 控制項資料繫結和檢視資料
更新:2007 年 11 月
您可使用 ObjectList ASP.NET Mobile 控制項提供更多用途的資料檢視。這個控制項顯示兩個資料來源檢視,顯示每個項目的摘要的清單檢視,及顯示項目詳細資訊的檢視。您可為每個項目明確定義想要顯示的清單欄位,或是從資料來源自動產生清單欄位。根據預設,控制項會根據顯示於資料來源中的欄位順序,為資料來源中的每個欄位產生欄位。每個自動產生的欄位的名稱則是當做欄位標題。
您可以將 ObjectList 控制項中的資料繫結至 DataView 或 DataSet 物件。若要將 ObjectList 行動控制項中的資料繫結至 DataView 物件,請設定 DataSource 屬性,然後呼叫 DataBind 方法以執行資料繫結 (Data Binding)。例如,如果您的 DataSet 物件具有名為 Titles 的資料表,便可使用下列陳述式執行資料繫結:
myObjectList.DataSource = ds.Tables["Titles"].DefaultView;
myObjectList.DataBind();
或者,若要將資料直接繫結至 DataSet 物件,您還必須將 DataMember 屬性設定為該資料表的名稱。下列範例的作用與上一個範例相同:
myObjectList.DataSource = ds;
myObjectList.DataMember = "Titles";
myObjectList.DataBind();
您也可將項目欄位設定為由數個資料項目的屬性所組成的值。若要執行這項作業,您可以覆寫 ObjectList 控制項的 ItemDataBind 事件,並且以程式設計方式設定此欄位。下列範例會將 Summary 欄位設定為書籍之書名與價格的組合:
private void ObjectList_OnItemDataBind(Object sender,
ObjectListDataBindEventArgs e)
{
e.ListItem["Summary"] = String.Format( String.Format ("{0} – {1}",
DataBinder.Eval(e.DataItem, "title"),
DataBinder.Eval (e.DataItem, "price")));
}
此外,您可控制如何在清單檢視中呈現每個項目。根據預設,清單檢視會使用第一個欄位來代表每個項目。然而,您可將 LabelField 屬性設定為任何已定義或已自動產生的欄位,包括詳細資料檢視中之不可見的欄位。在上一個範例中,您可以使用 Summary 欄位當做項目的標籤 (Label),同時在詳細資料檢視中隱藏這個欄位。
在 ObjectList 內執行資料繫結
ObjectList 控制項只會在其繫結至資料來源時才顯示內容。資料來源可以是實作 IEnumerable 介面或 IListSource 介面的任何物件。然而,資料來源中的每個物件必須屬於同一類別,或必須繼承自同一通用類別。當 AutoGenerateFields 設定為 true 時,資料來源中的物件就必須屬於相同類別 (Class)。
對於資料來源中的每個物件,ObjectList 控制項都會建構 ObjectListItem 執行個體 (Instance),並且將此執行個體儲存至其 Items 集合中。您可以透過程式碼檢查這個集合,但是不能加以修改。
物件清單參考的所有屬性都必須是資料來源中所有物件通用的類別的公用 (Public) 屬性。欄位參考的所有屬性也必須屬於可繫結型別。有效的可繫結型別包括 String、DateTime、Decimal,以及基本型別 (Primitive Type)。
針對資料來源中的每個物件,控制項執行下列資料繫結步驟:
對於每個欄位,ObjectList 控制項都會使用欄位的 DataField 屬性來決定要查詢資料物件的哪項屬性。每個值都是當做索引欄位值儲存至 ObjectListItem 執行個體中。
當所有欄位皆以此方式繫結之後,控制項便會呼叫已針對 ObjectList 控制項定義的任何 ItemDataBind 事件處理常式。您可使用這個處理常式進行更複雜的資料繫結,以及設定 ObjectListItem 執行個體中的值。
注意事項: 對 ObjectList 控制項進行的某些變更需要重新繫結該控制項上的資料。這些變更包括加入或移除欄位、變更欄位的 DataField 屬性,以及變更欄位的 DataFormatString 屬性。
在資料繫結期間起始自動產生欄位
在資料繫結時,如果將 AutoGenerateFields 屬性設定為 true,ObjectList 控制項便會檢查資料來源,然後自動產生欄位。如果資料來源是型別 ITypedList 的型別清單,ObjectList 控制項便會檢查該型別的資訊。否則,ObjectList 控制項便會檢查清單中第一個物件的型別資訊。
對於所檢查型別的每個可繫結公用屬性,ObjectList 控制項都會產生繫結至該屬性的欄位。這個作業會在資料繫結時發生,如果您變更欄位,或是加入、移除欄位,您就必須再次繫結該屬性。
根據預設,自動產生的欄位是可見的、使用預設格式,以及具有與該屬性名稱相同的標題。所有這些值都可用程式設計方式加以變更。此外,您也可以將 ObjectListTitleAttribute 屬性 (Attribute) 加入至屬性 (Property) 以指定欄位的標題。例如,如果物件具有宣告為 [ObjectListTitle("Address")]myAddress 的屬性,則產生的欄位具有標題「Address」。
如果 ObjectList 控制項具有明確定義的欄位,這些欄位後面就會加入自動產生的欄位。
下列範例會示範如何在 ObjectList 控制項中顯示自訂物件的清單。
<%@ Page Language="VB"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<script >
Private customers(3) As Person
Private Class Person
Private _Name, _Nickname, _Initials As String
Public Sub New(ByVal name As String, _
ByVal nickname As String, _
ByVal initials As String)
Me._Name = name
Me._Nickname = nickname
Me._Initials = initials
End Sub
Public ReadOnly Property Name() As String
Get
Return _Name
End Get
End Property
Public ReadOnly Property Nickname() As String
Get
Return _Nickname
End Get
End Property
Public ReadOnly Property Initials() As String
Get
Return _Initials
End Get
End Property
End Class
Private Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs)
ReDim customers(2)
customers(0) = _
New Person("George Washington", "George", "GW")
customers(1) = _
New Person("Abraham Lincoln", "Abe", "AL")
customers(2) = _
New Person("Theodore Roosevelt", "Teddy", "TR")
If (Not IsPostBack) Then
' Bind the array to the list.
List1.DataSource = customers
List1.DataTextField = "Name"
List1.DataBind()
End If
End Sub
Protected Sub List1_ItemCommand( _
ByVal sender As Object, _
ByVal e As ListCommandEventArgs)
' Show the Summary text
Dim selectedPerson As Person = _
customers(e.ListItem.Index)
Label1.Text = _
String.Format("{0} (AKA {1}), initials {2}", _
selectedPerson.Name, _
selectedPerson.Nickname, _
selectedPerson.Initials)
ActiveForm = Form2
End Sub
Protected Sub Command1_Click(ByVal sender As Object, _
ByVal e As EventArgs)
Me.ActiveForm = Me.Form1
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:form id="Form1" >
<mobile:List ID="List1" Runat="server"
OnItemCommand="List1_ItemCommand" />
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" />
<mobile:Command ID="Command1" Runat="server"
StyleReference="subcommand"
OnClick="Command1_Click">
Return</mobile:Command>
</mobile:Form>
</body>
</html>
<%@ Page Language="C#"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>
<script >
private ArrayList customers = new ArrayList();
private class Person
{
private String _Name, _Nickname, _Initials;
public Person(String name, String nickname, String initials)
{
this._Name = name;
this._Nickname = nickname;
this._Initials = initials;
}
public String Name { get { return _Name; } }
public String Nickname { get { return _Nickname; } }
public String Initials { get { return _Initials; } }
}
private void Page_Load(object sender, System.EventArgs e)
{
customers.Add(
new Person("George Washington", "George", "GW"));
customers.Add(
new Person("Abraham Lincoln", "Abe", "AL"));
customers.Add(
new Person("Theodore Roosevelt", "Teddy", "TR"));
if(!IsPostBack)
{
// Bind the array to the list.
List1.DataSource = customers;
List1.DataTextField = "Name";
List1.DataBind();
}
}
private void List1_ItemCommand(object sender,
ListCommandEventArgs e)
{
Person selectedPerson = (Person)customers[e.ListItem.Index];
Label1.Text = String.Format("{0} (AKA {1}), initials {2}",
selectedPerson.Name, selectedPerson.Nickname,
selectedPerson.Initials);
ActiveForm = Form2;
}
protected void Command1_Click(object sender, EventArgs e)
{
this.ActiveForm = this.Form1;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:form id="Form1" >
<mobile:List ID="List1" Runat="server"
OnItemCommand="List1_ItemCommand">
</mobile:List>
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" />
<mobile:Command ID="Command1" Runat="server"
OnClick="Command1_Click">Return</mobile:Command>
</mobile:Form>
</body>
</html>
在物件清單內產生命令的關聯
ObjectList 控制項允許和項目關聯的命令集。每個命令都具有用於唯一識別命令的 Name 屬性,以及用於呈現該命令的 Text 屬性。
控制項提供兩個定義命令的方式:
以宣告方式,方法是使用 ObjectList 控制項內的 <Command> 子項目。
以程式設計方式,方法是建構 Commands 物件,並將這些物件加入至控制項的 ObjectListCommand 集合。
根據預設,清單中的所有項目都共用同一命令集。然而,在呈現指定項目的命令集之前,控制項會引發 ShowItemCommands 事件。事件處理常式可使用這個方法來修改項目的可見命令集。
當使用者選取命令時,ItemCommand 事件將會引發,同時會顯示所選取項目的相關資訊和所選取命令的名稱。
即使您為項目定義其預設命令,您仍然必須以相同名稱將命令加入 Commands 集合中。如果控制項無法呈現包含預設命令捷徑的 UI,則控制項必須以做為命令集的一部分來顯示預設命令。
存取清單項目的欄位值
當您使事件處理常式與 ObjectList 控制項關聯時,該控制項便會將清單項目呈現為互動項目。按一下清單中的某個項目,便會產生擷取該項目之適當動作的事件。在資料繫結期間,會將每個欄位繫結至其相對應屬性。
若要擷取 ObjectListItem 物件的欄位值,請使用下列語法,其中 lstItem 是一個 ObjectListItem 執行個體:
lstItem[fieldName]
下列範例相似於上一個範例,但是它是對每筆記錄使用兩個 Command 控制項,同時是使用欄位語法來擷取欄位值:
<%@ Page Language="VB"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>
<script >
Public Class Person
' Private Fields
Private _Name, _Nickname, _Initials, _Wife As String
' Constructor
Public Sub New(ByVal name As String, _
ByVal nickname As String, ByVal initials As String, _
ByVal wife As String)
Me._Name = name
Me._Nickname = nickname
Me._Initials = initials
Me._Wife = wife
End Sub
' Public Properties
Public ReadOnly Property Name()
Get
Return _Name
End Get
End Property
Public ReadOnly Property Nickname()
Get
Return _Nickname
End Get
End Property
Public ReadOnly Property Initials()
Get
Return _Initials
End Get
End Property
Public ReadOnly Property Wife()
Get
Return _Wife
End Get
End Property
End Class
Private Sub Page_Load(ByVal sender As Object, _
ByVal e As EventArgs)
If Not IsPostBack Then
' An ArrayList for the Person objects
Dim customers As New ArrayList()
customers.Add( _
New Person("George Washington", "George", _
"GW", "Martha"))
customers.Add( _
New Person("Abraham Lincoln", "Abe", _
"AL", "Mary"))
customers.Add( _
New Person("Theodore Roosevelt", "Teddy", _
"TR", "Alice Lee"))
' Bind the array to the list.
ObjectList1.DataSource = customers
ObjectList1.LabelField = "Name"
ObjectList1.DataBind()
End If
End Sub
Protected Sub ObjectList1_ItemCommand( _
ByVal sender As Object, _
ByVal e As ObjectListCommandEventArgs)
If e.CommandName = "ShowSummary" Then
' Show the Summary text
Label1.Text = _
String.Format("{0}, AKA: '{1}', initials: '{2}'", _
e.ListItem("Name"), e.ListItem("Nickname"), _
e.ListItem("Initials"))
ElseIf e.CommandName = "MoreInfo" Then
' Show the More Info text
Label1.Text = String.Format("{0}'s wife was {1}", _
e.ListItem("Nickname"), e.ListItem("Wife"))
End If
Me.ActiveForm = Form2
End Sub
Protected Sub Command1_Click(ByVal sender As Object, _
ByVal e As EventArgs)
' Show the first form
Me.ActiveForm = Form1
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:form id="Form1" >
<mobile:ObjectList ID="ObjectList1" Runat="server"
CommandStyle-StyleReference="subcommand"
LabelStyle-StyleReference="title"
OnItemCommand="ObjectList1_ItemCommand">
<Command Name="ShowSummary" Text="Summary" />
<Command Name="MoreInfo" Text="More Info" />
</mobile:ObjectList>
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" />
<mobile:Command ID="Command1" Runat="server"
OnClick="Command1_Click">Return
</mobile:Command>
</mobile:Form>
</body>
</html>
<%@ Page Language="C#"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>
<script >
private class Person
{
// Private Fields
private String _Name, _Nickname, _Initials, _Wife;
// Constructor
public Person(string name, string nickname,
string initials, string wife)
{
this._Name = name;
this._Nickname = nickname;
this._Initials = initials;
this._Wife = wife;
}
// Public Properties
public String Name { get { return _Name; } }
public String Nickname { get { return _Nickname; } }
public String Initials { get { return _Initials; } }
public String Wife { get { return _Wife; } }
}
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
// An ArrayList for the Person objects
ArrayList customers = new ArrayList();
// Fill the Person object
customers.Add(
new Person("George Washington", "George",
"GW", "Martha"));
customers.Add(
new Person("Abraham Lincoln", "Abe",
"AL", "Mary"));
customers.Add(
new Person("Theodore Roosevelt", "Teddy",
"TR", "Alice Lee"));
// Bind the array to the list.
ObjectList1.DataSource = customers;
ObjectList1.LabelField = "Name";
ObjectList1.DataBind();
}
}
protected void ObjectList1_ItemCommand
(object sender, ObjectListCommandEventArgs e)
{
if (e.CommandName == "ShowSummary")
{
// Show the Summary text
Label1.Text =
String.Format("{0}, AKA: '{1}', initials: '{2}'",
e.ListItem["Name"], e.ListItem["Nickname"],
e.ListItem["Initials"]);
}
else if (e.CommandName == "MoreInfo")
{
// Show the More Info text
Label1.Text = String.Format("{0}'s wife was {1}",
e.ListItem["Nickname"], e.ListItem["Wife"]);
}
this.ActiveForm = Form2;
}
protected void Command1_Click(object sender, EventArgs e)
{
// Show the first form
this.ActiveForm = Form1;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<mobile:form id="Form1" >
<mobile:ObjectList ID="ObjectList1" Runat="server"
CommandStyle-StyleReference="subcommand"
LabelStyle-StyleReference="title"
OnItemCommand="ObjectList1_ItemCommand">
<Command Name="ShowSummary" Text="Summary" />
<Command Name="MoreInfo" Text="More Info" />
</mobile:ObjectList>
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" />
<mobile:Command ID="Command1" Runat="server"
OnClick="Command1_Click">Return
</mobile:Command>
</mobile:Form>
</body>
</html>
ObjectList 樣板中的資料繫結
在 ObjectList 控制項中,您可定義樣板來自訂使用者的使用經驗。如果您要使用樣板進行內嵌 (Inline) 資料繫結,請使用類似下列的語法:
<%#((ObjectListItem)Container)["BookName"]%>
您也可以使用 DataBinder.Eval 方法來繫結所有樣板中的資料,如下列範例所示:
<%#DataBinder.Eval(((ObjectListItem)Container).DataItem,"fieldname")%>