Datenbindung und Anzeigen von Daten mit einem ObjectList-Steuerelement
Aktualisiert: November 2007
Sie können mit dem ObjectList-ASP.NET Mobile-Steuerelement eine vielseitige Ansicht von Daten bereitstellen. Dieses Steuerelement zeigt zwei Ansichten der Datenquelle an: eine Listenansicht, die eine Zusammenfassung für jedes Element anzeigt, und eine Ansicht, die Einzelheiten zu den Elementen aufführt. Sie können die Listenfelder, die für jedes Element angezeigt werden sollen, explizit definieren oder automatisch aus der Datenquelle generieren lassen. Das Steuerelement erzeugt standardmäßig für jedes Feld in der Datenquelle ein Feld in der Reihenfolge, in der die Felder in der Datenquelle angezeigt werden. Der Name jedes automatisch erzeugten Felds wird als Feldtitel verwendet.
Sie können Daten in einem ObjectList-Steuerelement an ein DataView-Objekt oder ein DataSet-Objekt binden. Um Daten in einem mobilen ObjectList-Steuerelement an ein DataView-Objekt zu binden, legen Sie die DataSource-Eigenschaft fest und rufen dann die DataBind-Methode auf, um die Datenbindung durchzuführen. Sie können zum Beispiel bei einem DataSet-Objekt mit der Tabelle Titles folgende Anweisungen zum Ausführen der Datenbindung verwenden:
myObjectList.DataSource = ds.Tables["Titles"].DefaultView;
myObjectList.DataBind();
Wenn Sie alternativ dazu Daten direkt an ein DataSet-Objekt binden möchten, müssen Sie zusätzlich die DataMember-Eigenschaft auf den Namen der Tabelle festlegen. Das folgende Beispiel entspricht dem vorhergehenden:
myObjectList.DataSource = ds;
myObjectList.DataMember = "Titles";
myObjectList.DataBind();
Sie können außerdem ein Feld für ein Element auf einen Wert festlegen, der aus mehreren Eigenschaften des Datenelements zusammengesetzt ist. Hierzu können Sie das ItemDataBind-Ereignis des ObjectList-Steuerelements überschreiben und das Feld programmgesteuert festlegen. Im folgenden Beispiel wird das Summary-Feld auf eine Kombination aus Titel und Preis eines Buchs festgelegt.
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")));
}
Außerdem können Sie steuern, wie jedes Element in der Listenansicht wiedergegeben wird. Standardmäßig wird in der Listenanzeige jedes Element im ersten Feld wiedergegeben. Sie können aber die LabelField-Eigenschaft auf jedes definierte oder automatisch erzeugte Feld festlegen, selbst wenn es nicht in der Detailansicht angezeigt wird. Mit dem vorhergehenden Beispiel können Sie das Summary-Feld als Bezeichnung für ein Element verwenden und es gleichzeitig in der Detailansicht ausblenden.
Ausführen von Datenbindung in einer ObjectList
Ein ObjectList-Steuerelement zeigt nur dann Inhalte an, wenn es an eine Datenquelle gebunden ist. Die Datenquelle kann jedes Objekt sein, das die IEnumerable-Schnittstelle oder die IListSource-Schnittstelle implementiert. Jedes Objekt in der Datenquelle muss jedoch zu derselben Klasse gehören oder von derselben allgemeinen Klasse erben. Wenn AutoGenerateFields auf true festgelegt wird, müssen die Objekte in der Datenquelle von derselben Klasse sein.
Für jedes Objekt in der Datenquelle erstellt das ObjectList-Steuerelement eine ObjectListItem-Instanz und speichert diese in seiner Items-Auflistung. Diese Auflistung kann vom Code überprüft, jedoch nicht geändert werden.
Bei allen Eigenschaften, auf die die Objektliste verweist, muss es sich um öffentliche Eigenschaften einer Klasse handeln, die allen Objekten in der Datenquelle gemeinsam ist. Alle Eigenschaften, auf die Felder verweisen, müssen ebenfalls gebunden werden können. Gültige bindungsfähige Typen sind String, DateTime, Decimal und der Satz von primitiven Typen.
Für jedes Objekt in der Datenquelle führt das Steuerelement folgende Schritte für die Datenbindung durch:
Für jedes Feld bestimmt das ObjectList-Steuerelement anhand der DataField-Eigenschaft des Felds die zu suchende Eigenschaft des Datenobjekts. Jeder Wert wird in der ObjectListItem-Instanz als indizierter Feldwert gespeichert.
Nachdem alle Felder auf diese Weise gebunden wurden, ruft das Steuerelement sämtliche für das ObjectList-Steuerelement definierten ItemDataBind-Ereignishandler auf. Sie können diesen Handler für eine komplexere Datenbindung und zum Festlegen von Werten in der ObjectListItem-Instanz verwenden.
Hinweis:
Bei einigen Änderungen an einem ObjectList-Steuerelement müssen die Daten erneut an dieses Steuerelement gebunden werden. Zu diesen Änderungen zählen das Hinzufügen oder Entfernen von Feldern, das Ändern der DataField-Eigenschaft eines Felds und das Ändern der DataFormatString-Eigenschaft eines Felds.
Initialisieren der automatischen Generierung von Feldern während der Datenbindung
Wenn die AutoGenerateFields-Eigenschaft auf true festgelegt ist, überprüft das ObjectList-Steuerelement bei der Datenbindung die Datenquelle und generiert dann automatisch Felder. Wenn es sich bei der Datenquelle um eine Liste vom Typ ITypedList handelt, überprüft das ObjectList-Steuerelement die Informationen für den Typ. Andernfalls überprüft das ObjectList-Steuerelement die Typinformationen des ersten Objekts in der Liste.
Für jede bindbare öffentliche Eigenschaft des überprüften Typs generiert das ObjectList-Steuerelement ein an die Eigenschaft gebundenes Feld. Dies geschieht während der Datenbindung. Wenn Sie Änderungen an einem Feld vornehmen oder Felder hinzufügen bzw. entfernen, müssen die Eigenschaften erneut gebunden werden.
Standardmäßig sind automatisch generierte Felder sichtbar, verwenden die Standardformatierung und haben denselben Titel wie der Eigenschaftenname. Alle diese Werte können programmgesteuert geändert werden. Außerdem können Sie den Titel des Felds angeben, indem Sie der Eigenschaft ein ObjectListTitleAttribute-Attribut hinzufügen. Wenn das Objekt beispielsweise über eine als [ObjectListTitle("Address")]myAddress deklarierte Eigenschaft verfügt, lautet der Titel des generierten Felds "Address."
Wenn das ObjectList-Steuerelement explizit definierte Felder enthält, werden die automatisch generierten Felder nach diesen hinzugefügt.
Das folgende Beispiel zeigt, wie eine Liste benutzerdefinierter Objekte in einem ObjectList-Steuerelement angezeigt wird.
<%@ Page Language="VB"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<script runat="server">
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" runat="server">
<mobile:List ID="List1" Runat="server"
OnItemCommand="List1_ItemCommand" />
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" runat="server" />
<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 runat="server">
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" runat="server">
<mobile:List ID="List1" Runat="server"
OnItemCommand="List1_ItemCommand">
</mobile:List>
</mobile:form>
<mobile:Form ID="Form2" Runat="server">
<mobile:Label ID="Label1" runat="server" />
<mobile:Command ID="Command1" Runat="server"
OnClick="Command1_Click">Return</mobile:Command>
</mobile:Form>
</body>
</html>
Zuordnen von Befehlen in einer Objektliste
Mit dem ObjectList-Steuerelement kann ein Befehlssatz einem Element zugeordnet werden. Jeder Befehl besitzt eine Name-Eigenschaft, mit der er eindeutig gekennzeichnet wird, und eine Text-Eigenschaft für die Wiedergabe des Befehls.
Das Steuerelement bietet zwei Möglichkeiten zum Definieren von Befehlen:
Deklarativ, durch Verwenden von untergeordneten <Command>-Elementen in einem ObjectList-Steuerelement.
Programmgesteuert, durch Erstellen von ObjectListCommand-Objekten und deren Hinzufügen zur Commands-Auflistung des Steuerelements.
Standardmäßig verwenden alle Elemente der Liste denselben Satz von Befehlen. Das Steuerelement löst jedoch das ShowItemCommands-Ereignis aus, bevor der Befehlssatz für ein bestimmtes Element wiedergegeben wird. Mithilfe dieser Methode kann ein Ereignishandler den sichtbaren Befehlssatz für das Element ändern.
Wenn der Benutzer einen Befehl auswählt, wird ein ItemCommand-Ereignis mit Informationen über das ausgewählte Element und den Namen des ausgewählten Befehls ausgelöst.
Auch wenn Sie einen Standardbefehl für ein Element definieren, müssen Sie der Commands-Auflistung einen Befehl mit demselben Namen hinzufügen. Wenn das Steuerelement eine Benutzeroberfläche nicht darstellen kann, die eine Verknüpfung mit dem Standardbefehl enthält, muss es den Standardbefehl als Teil des Befehlssatzes anzeigen.
Zugreifen auf Feldwerte eines Listenelements
Wenn Sie einem ObjectList-Steuerelement einen Ereignishandler zuordnen, gibt es Listenelemente als interaktive Elemente wieder. Beim Klicken auf ein Element in einer Liste wird ein Ereignis generiert, das die entsprechende Aktion für dieses Element abruft. Während der Datenbindung wird jedes Feld an dessen entsprechende Eigenschaft gebunden.
Zum Abrufen eines Feldwerts von einem ObjectListItem-Objekt verwenden Sie folgende Syntax, wobei lstItem eine ObjectListItem-Instanz ist:
lstItem[fieldName]
Das folgende Beispiel ähnelt dem vorhergehenden, verwendet aber zwei Command-Steuerelemente pro Datensatz und die Feldsyntax zum Abrufen von Feldwerten:
<%@ 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 runat="server">
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" runat="server">
<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" runat="server" />
<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 runat="server">
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" runat="server">
<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" runat="server" />
<mobile:Command ID="Command1" Runat="server"
OnClick="Command1_Click">Return
</mobile:Command>
</mobile:Form>
</body>
</html>
Datenbindung in ObjectList-Vorlagen
Im ObjectList-Steuerelement können Sie Vorlagen zum Anpassen an Benutzer definieren. Wenn Sie in Vorlagen Inlinedatenbindung durchführen, verwenden Sie die folgende Syntax:
<%#((ObjectListItem)Container)["BookName"]%>
Sie können auch mit der DataBinder.Eval-Methode Daten in allen Vorlagen binden, wie das folgende Beispiel zeigt:
<%#DataBinder.Eval(((ObjectListItem)Container).DataItem,"fieldname")%>