Associazione dati e visualizzazione dei dati mediante un controllo ObjectList

Aggiornamento: novembre 2007

È possibile utilizzare il controllo mobile ASP.NET ObjectList per garantire una visualizzazione versatile dei dati. Il controllo consente due visualizzazioni dell'origine dati, un elenco in cui è riportato un riepilogo di ciascun elemento e una visualizzazione con i dettagli degli elementi. È possibile definire in modo esplicito i campi dell'elenco che si desidera visualizzare per ciascun elemento oppure generarli automaticamente dall'origine dati. Per impostazione predefinita, il controllo genera un campo per ciascun campo dell'origine dati, nell'ordine in cui viene visualizzato nell'origine dati. Il nome di ogni campo generato automaticamente viene utilizzato come titolo del campo.

È possibile associare i dati di un controllo ObjectList a un oggetto DataView o DataSet. Per associare i dati di un controllo mobile ObjectList a un oggetto DataView, impostare la proprietà DataSource, quindi chiamare il metodo DataBind per eseguire l'associazione dati. Se ad esempio si dispone di un oggetto DataSet con una tabella denominata Titles, è possibile utilizzare le istruzioni riportate di seguito per eseguire l'associazione dati:

myObjectList.DataSource = ds.Tables["Titles"].DefaultView;
myObjectList.DataBind();

In alternativa, per associare i dati direttamente a un oggetto DataSet, è inoltre necessario impostare la proprietà DataMember sul nome della tabella. L'esempio che segue equivale a quello precedente:

myObjectList.DataSource = ds;
myObjectList.DataMember = "Titles";
myObjectList.DataBind();

È anche possibile impostare un campo di elemento su un valore composto da diverse proprietà dell'elemento di dati. A tale scopo, è possibile eseguire l'override dell'evento ItemDataBind del controllo ObjectList e impostare il campo a livello di codice. Nell'esempio riportato di seguito il campo Summary viene impostato su una combinazione di titolo e prezzo di un libro:

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")));
}

È inoltre possibile controllare il modo in cui viene eseguito il rendering di ciascun elemento nell'elenco. Per impostazione predefinita, nell'elenco è il primo campo a rappresentare ciascun elemento. È tuttavia possibile impostare la proprietà LabelField su qualsiasi campo definito o generato in modo automatico, incluso un campo non visibile nella visualizzazione Dettagli. Avvalendosi del precedente esempio, è possibile utilizzare il campo Summary come etichetta di un elemento, nascondendolo poi nella visualizzazione Dettagli.

Esecuzione dell'associazione dati in un controllo ObjectList

Un controllo ObjectList consente di visualizzare il contenuto solo se è associato a un'origine dati. L'origine dati può essere qualsiasi oggetto in cui sia implementata l'interfaccia IEnumerable o IListSource. Tuttavia, ogni oggetto dell'origine dati deve appartenere alla stessa classe o ereditare dalla stessa classe comune. Quando la proprietà AutoGenerateFields è impostata su true, gli oggetti dell'origine dati devono essere della stessa classe.

Per ciascun oggetto dell'origine dati, il controllo ObjectList consente di costruire un'istanza della classe ObjectListItem e di archiviarla nel relativo insieme Items. L'insieme può essere esaminato, ma non modificato, mediante il codice.

Tutte le proprietà a cui fa riferimento l'elenco di oggetti devono essere di tipo pubblico e appartenere a una classe comune a tutti gli oggetti dell'origine dati. Tutte le proprietà a cui fanno riferimento i campi devono inoltre essere di tipo associabile. Sono tipi associabili validi String, DateTime, Decimal e l'insieme di tipi primitivi.

Per ciascun oggetto dell'origine dati vengono effettuati i seguenti passaggi di associazione dati:

  1. Per ciascun campo, il controllo ObjectList utilizza la proprietà DataField del campo per determinare quale proprietà dell'oggetto dati ricercare. Ogni valore viene salvato nell'istanza della classe ObjectListItem come valore di campo indicizzato.

  2. Una volta associati tutti i campi secondo la procedura descritta, viene chiamato uno dei gestori eventi ItemDataBind definiti per il controllo ObjectList. Tale gestore può essere utilizzato per eseguire un'associazione dati più complessa e impostare i valori nell'istanza della classe ObjectListItem.

    Nota:

    Per apportare modifiche a un controllo ObjectList è necessario riassociarne i dati. Tra le modifiche previste sono incluse l'aggiunta e la rimozione di campi e la modifica delle proprietà DataField e DataFormatString di un campo.

Avvio della generazione automatica dei campi durante l'associazione dati

Durante l'associazione dati, se la proprietà AutoGenerateFields è impostata su true, il controllo ObjectList esamina l'origine dati e genera automaticamente i campi. Se l'origine dati è un elenco di tipo ITypedList, il controllo ObjectList esamina le informazioni relative al tipo. Altrimenti, il controllo ObjectList esamina le informazioni sui tipi del primo oggetto dell'elenco.

Per ciascuna proprietà pubblica associabile del tipo esaminato, il controllo ObjectList genera un campo associato alla proprietà. Questo avviene durante l'associazione dati. Se si apportano modifiche a un campo oppure si aggiungono o rimuovono campi, è necessario riassociare le proprietà.

Per impostazione predefinita, i campi generati automaticamente sono visibili, presentano come titolo il nome della proprietà e per essi viene utilizzata la formattazione predefinita. Tutti questi valori possono essere modificati a livello di codice. È inoltre possibile specificare il titolo del campo aggiungendo un attributo ObjectListTitleAttribute alla proprietà. Se, ad esempio, l'oggetto presenta una proprietà dichiarata come [ObjectListTitle("Address")]myAddress, il titolo del campo generato sarà "Address".

Se nel controllo ObjectList sono presenti campi definiti in modo esplicito, i campi generati automaticamente vengono aggiunti dopo di essi.

Nell'esempio riportato di seguito viene descritto come visualizzare un elenco di oggetti personalizzati in un controllo 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>

Associazione di comandi in un elenco di oggetti

Il controllo ObjectList consente di associare un insieme di comandi a un elemento. Ogni comando dispone di una proprietà Name utilizzata per identificare in modo univoco il comando e di una proprietà Text utilizzata per eseguire il rendering del comando.

I comandi possono essere definiti in due modi:

Per impostazione predefinita, tutte gli elementi dell'elenco condividono lo stesso insieme di comandi. Tuttavia, prima di eseguire il rendering dell'insieme di comandi relativo a un determinato elemento, viene generato l'evento ShowItemCommands. Questo metodo può essere utilizzato da un gestore eventi per modificare l'insieme dei comandi visibili relativi all'elemento in questione.

Quando l'utente seleziona un comando, viene generato un evento ItemCommand con le informazioni relative all'elemento selezionato e il nome del comando scelto.

Anche se si definisce un comando predefinito per un elemento, è necessario includere un comando con lo stesso nome nell'insieme Commands. Se il controllo non è in grado di eseguire il rendering di un elemento di interfaccia utente in cui sia incluso un collegamento al comando predefinito, deve visualizzare tale comando come parte dell'insieme dei comandi.

Accesso ai valori dei campi di un elemento dell'elenco

Quando si associa un gestore eventi a un controllo ObjectList, gli elementi vengono visualizzati come elementi interattivi. Facendo clic su un elemento in un elenco viene generato un evento che recupera l'azione appropriata per l'elemento. Durante l'associazione dati, ciascun campo viene associato alla proprietà corrispondente.

Per recuperare il valore di un campo da un oggetto ObjectListItem, utilizzare la sintassi riportata di seguito, dove lstItem è un'istanza della classe ObjectListItem.

lstItem[fieldName]

L'esempio riportato di seguito è simile all'esempio precedente, ma vengono utilizzati due controlli Command per ogni record, nonché la sintassi del campo per recuperare i valori del campo:

<%@ 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>

Associazione dati nei modelli ObjectList

Nel controllo ObjectList è possibile definire modelli per personalizzare l'attività dell'utente. Se si esegue l'associazione dati inline in tali modelli, utilizzare una sintassi simile alla seguente:

<%#((ObjectListItem)Container)["BookName"]%> 

È inoltre possibile utilizzare il metodo DataBinder.Eval per associare dati in tutti i modelli, come indicato nell'esempio riportato di seguito:

<%#DataBinder.Eval(((ObjectListItem)Container).DataItem,"fieldname")%>

Vedere anche

Concetti

Accesso ai dati mediante i controlli elenco