Liaison de données et affichage de données via un contrôle ObjectList
Mise à jour : novembre 2007
Vous pouvez utiliser le contrôle mobile ASP.NET ObjectList pour fournir une vue polyvalente des données. Ce contrôle affiche deux vues de votre source de données, un mode Liste qui montre un résumé de chaque élément et une vue qui montre les détails de l'élément. Vous pouvez définir explicitement les champs de liste à afficher pour chaque élément, ou les générer automatiquement à partir de la source de données. Par défaut, le contrôle génère un champ pour chaque champ de la source de données, dans l'ordre où il figure dans la source de données. Le nom de chaque champ généré automatiquement est utilisé en tant que titre du champ.
Vous pouvez lier des données dans un contrôle ObjectList à un objet DataView ou DataSet. Pour lier des données dans un contrôle mobile ObjectList à un objet DataView, définissez la propriété DataSource, puis appelez la méthode DataBind afin d'effectuer la liaison de données. Par exemple, si vous disposez d'un objet DataSet avec une table nommée Titles, vous pouvez utiliser les instructions suivantes pour effectuer la liaison de données :
myObjectList.DataSource = ds.Tables["Titles"].DefaultView;
myObjectList.DataBind();
Par ailleurs, pour lier des données directement à un objet DataSet, vous devez en plus affecter le nom de la table à la propriété DataMember. L'exemple suivant équivaut au précédent :
myObjectList.DataSource = ds;
myObjectList.DataMember = "Titles";
myObjectList.DataBind();
Vous pouvez également affecter au champ d'un élément une valeur composée de plusieurs des propriétés de l'élément de données. Pour ce faire, vous pouvez substituer l'événement ItemDataBind du contrôle ObjectList, puis définir le champ par programme. L'exemple suivant affecte au champ Summary une valeur qui combine le titre et le prix d'un livre :
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")));
}
En outre, vous pouvez contrôler le rendu de chaque élément dans le mode Liste. Par défaut, le mode Liste utilise le premier champ pour représenter chaque élément. Cependant, vous pouvez affecter à la propriété LabelField un champ spécifique ou généré automatiquement, y compris un champ non visible en mode Détails. En reprenant l'exemple précédent, vous pouvez utiliser le champ Summary en tant qu'étiquette d'un élément, tout en le masquant en mode Détails.
Liaison de données dans ObjectList
Un contrôle ObjectList n'affiche un contenu que s'il est dépendant d'une source de données. La source de données peut être n'importe quel objet implémentant l'interface IEnumerable ou IListSource. Cependant, chaque objet de la source de données doit appartenir à la même classe ou hériter d'une classe commune. Lorsque AutoGenerateFields a la valeur true, les objets de la source de données doivent appartenir à la même classe.
Pour chaque objet de la source de données, le contrôle ObjectList construit une instance ObjectListItem et la stocke dans sa collection Items. Cette collection peut être inspectée, mais pas modifiée, par votre code.
Toutes les propriétés auxquelles la liste d'objets fait référence doivent être des propriétés publiques d'une classe commune à l'ensemble des objets de la source de données. En outre, tous les types des propriétés auxquelles les champs font référence doivent pouvoir être liés. Les types valides pouvant être liés sont String, DateTime, Decimal et l'ensemble des types primitifs.
Pour chaque objet de la source de données, le contrôle exécute les étapes suivantes en matière de liaison de données :
Pour chaque champ, le contrôle ObjectList utilise la propriété DataField du champ afin de déterminer la propriété de l'objet de données à rechercher. Chaque valeur est enregistrée dans l'instance ObjectListItem sous forme de valeur de champ indexé.
Une fois tous les champs liés de cette manière, le contrôle appelle n'importe quel gestionnaire d'événements ItemDataBind défini pour le contrôle ObjectList. Vous pouvez utiliser ce gestionnaire pour effectuer une liaison de données plus complexe, ainsi que pour définir des valeurs dans l'instance ObjectListItem.
Remarque : Certaines modifications apportées à un contrôle ObjectList vous obligent à réexécuter la liaison de données sur ce contrôle. Ces modifications comprennent l'ajout ou la suppression de champs, la modification de la propriété DataField d'un champ et celle de la propriété DataFormatString d'un champ.
Lancement de la génération automatique de champ durant la liaison de données
Lors de la liaison de données, si la propriété AutoGenerateFields a la valeur true, le contrôle ObjectList inspecte la source de données et génère automatiquement les champs. Si la source de données est une liste de type ITypedList, le contrôle ObjectList inspecte les informations relatives à ce type. Sinon, le contrôle ObjectList inspecte les informations de type du premier objet de la liste.
Pour chaque propriété publique pouvant être liée et appartenant au type inspecté, le contrôle ObjectList génère un champ lié à la propriété. Cela se produit lors de la liaison de données ; si vous apportez des modifications à un champ, ou si vous ajoutez ou supprimez des champs, vous devez à nouveau lier les propriétés.
Par défaut, les champs générés automatiquement sont visibles, ils utilisent la mise en forme par défaut et leur titre est identique au nom de la propriété. Toutes ces valeurs peuvent être modifiées par programme. De même, vous pouvez spécifier le titre du champ en ajoutant un attribut ObjectListTitleAttribute à la propriété. Par exemple, si l'objet dispose d'une propriété déclarée sous la forme [ObjectListTitle("Address")]myAddress, le champ généré se voit affecter le titre "Address".
Si le contrôle ObjectList possède des champs définis explicitement, les champs générés automatiquement sont ajoutés après ces derniers.
L'exemple suivant montre comment afficher une liste d'objets personnalisés dans un contrôle 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>
Associer des commandes dans une liste d'objets
Le contrôle ObjectList permet d'associer un ensemble de commandes à un élément. Chaque commande possède une propriété Name qui sert à l'identifier de manière unique, ainsi qu'une propriété Text qui permet de l'afficher.
Le contrôle permet de définir des commandes de deux manières :
De façon déclarative, en utilisant les éléments enfants <Command> dans un contrôle ObjectList.
Par programme, en construisant des objets ObjectListCommand et en les ajoutant à la collection Commands du contrôle.
Par défaut, tous les éléments de la liste partagent le même ensemble de commandes. Cependant, avant le rendu de l'ensemble de commandes d'un élément donné, le contrôle déclenche l'événement ShowItemCommands. Un gestionnaire d'événements peut utiliser cette méthode pour modifier l'ensemble de commandes visibles pour l'élément.
Lorsque l'utilisateur sélectionne une commande, un événement ItemCommand est déclenché ; il comprend les informations relatives à l'élément sélectionné ainsi que le nom de la commande sélectionnée.
Même si vous définissez une commande par défaut pour un élément, vous devez inclure une commande du même nom dans la collection Commands. Si le contrôle ne peut pas afficher une interface utilisateur comprenant un raccourci pour la commande par défaut, il doit afficher la commande par défaut faisant partie de l'ensemble de commandes.
Accès aux valeurs de champs d'un élément de liste
Lorsque vous associez un gestionnaire d'événements à un contrôle ObjectList, il affiche les éléments de liste sous forme d'éléments interactifs. Le fait de cliquer sur un élément dans une liste déclenche un événement qui récupère l'action appropriée pour cet élément. Lors de la liaison de données, chaque champ est lié à sa propriété correspondante.
Pour récupérer une valeur de champ d'un objet ObjectListItem, utilisez la syntaxe suivante, où lstItem représente une instance ObjectListItem.
lstItem[fieldName]
L'exemple suivant est semblable au précédent, mais il utilise deux contrôles Command pour chaque enregistrement et utilise la syntaxe de champ pour récupérer les valeurs de champs :
<%@ 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>
Liaison de données dans les modèles de ObjectList
Dans le contrôle ObjectList, vous pouvez définir des modèles pour personnaliser l'expérience utilisateur. Si vous effectuez des liaisons de données inline dans des modèles, utilisez une syntaxe telle que la suivante :
<%#((ObjectListItem)Container)["BookName"]%>
Vous pouvez également utiliser la méthode DataBinder.Eval pour lier des données dans tous les modèles, comme dans l'exemple suivant :
<%#DataBinder.Eval(((ObjectListItem)Container).DataItem,"fieldname")%>