Compartir a través de


Ejemplo de propiedad Collection de controles Web

Actualización: noviembre 2007

En este ejemplo se muestra cómo crear un control denominado QuickContacts que implementa la persistencia en una página para una propiedad de colección. El ejemplo incluye un control que permite a un desarrollador de páginas almacenar una lista de contactos de libreta de direcciones. El control QuickContacts expone una propiedad de colección Contacts que contiene objetos Contact. La clase Contact tiene las propiedades Name, Email y Phone.

Los elementos Contact de la propiedad de colección Contacts se conservan dentro de las etiquetas del control, como se muestra en el ejemplo siguiente:

<aspSample:QuickContacts ID="QuickContacts1" Runat="server">
  <aspSample:Contact Name="someone" Email="someone@example.com"     Phone="(555) 555-5555"/><aspSample:Contact Name="jae" Email="jae@fourthcoffee.com"     Phone="(555) 555-5555"/>
</aspSample:QuickContacts>

Por motivos de claridad, el control QuickContacts no implementa administración de estado para la propiedad de colección. Se supone que los elementos de la colección se agregan mediante declaración a la página, o bien, si se crean en código, es preciso volver a crearlos cuando se produce la devolución de datos. En un control con calidad de producción, se debería implementar la administración de estado. Para obtener información detallada, vea Administración de estados personalizados de controles de servidor.

Lista de código del control QuickContacts

' QuickContacts.vb
Option Strict On
Imports System
Imports System.ComponentModel
Imports System.Collections
Imports System.Drawing.Design
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Samples.AspNet.VB.Controls
    < _
    AspNetHostingPermission(SecurityAction.Demand, _
        Level:=AspNetHostingPermissionLevel.Minimal), _
    AspNetHostingPermission(SecurityAction.InheritanceDemand, _
        Level:=AspNetHostingPermissionLevel.Minimal), _
    DefaultProperty("Contacts"), _
    ParseChildren(True, "Contacts"), _
    ToolboxData( _
        "<{0}:QuickContacts runat=""server""> </{0}:QuickContacts>") _
    > _
    Public Class QuickContacts
        Inherits WebControl

        Private contactsList As ArrayList

        < _
        Category("Behavior"), _
        Description("The contacts collection"), _
        DesignerSerializationVisibility( _
            DesignerSerializationVisibility.Content), _
        Editor(GetType(ContactCollectionEditor), _
            GetType(UITypeEditor)), _
        PersistenceMode(PersistenceMode.InnerDefaultProperty) _
        > _
        Public ReadOnly Property Contacts() As ArrayList
            Get
                If contactsList Is Nothing Then
                    contactsList = New ArrayList
                End If
                Return contactsList
            End Get
        End Property

        ' The contacts are rendered in an HTML table.
        Protected Overrides Sub RenderContents( _
        ByVal writer As HtmlTextWriter)
            Dim t As Table = CreateContactsTable()
            If t IsNot Nothing Then
                t.RenderControl(writer)
            End If
        End Sub

        Private Function CreateContactsTable() As Table
            Dim t As Table = Nothing
            If (contactsList IsNot Nothing) AndAlso _
                (contactsList.Count > 0) Then
                t = New Table
                For Each item As Contact In contactsList
                    Dim aContact As Contact = TryCast(item, Contact)
                    If aContact IsNot Nothing Then
                        Dim r As New TableRow
                        Dim c1 As New TableCell
                        c1.Text = aContact.Name
                        r.Controls.Add(c1)

                        Dim c2 As New TableCell
                        c2.Text = aContact.Email
                        r.Controls.Add(c2)

                        Dim c3 As New TableCell
                        c2.Text = aContact.Phone
                        r.Controls.Add(c3)

                        t.Controls.Add(r)
                    End If
                Next
            End If
            Return t
        End Function
    End Class
End Namespace
// QuickContacts.cs
using System;
using System.ComponentModel;
using System.Collections;
using System.Drawing.Design;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Samples.AspNet.CS.Controls
{
    [
    AspNetHostingPermission(SecurityAction.Demand,
        Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand, 
        Level=AspNetHostingPermissionLevel.Minimal),
    DefaultProperty("Contacts"),
    ParseChildren(true, "Contacts"),
    ToolboxData(
        "<{0}:QuickContacts runat=\"server\"> </{0}:QuickContacts>")
    ]
    public class QuickContacts : WebControl
    {
        private ArrayList contactsList;

        [
        Category("Behavior"),
        Description("The contacts collection"),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        Editor(typeof(ContactCollectionEditor), typeof(UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerDefaultProperty)
        ]
        public ArrayList Contacts
        {
            get
            {
                if (contactsList == null)
                {
                    contactsList = new ArrayList();
                }
                return contactsList;
            }
        }


        // The contacts are rendered in an HTML table.
        protected override void RenderContents(
            HtmlTextWriter writer)
        {
            Table t = CreateContactsTable();
            if (t != null)
            {
                t.RenderControl(writer);
            }
        }

        private Table CreateContactsTable()
        {
            Table t = null;

            if (contactsList != null && contactsList.Count > 0)
            {
                t = new Table();

                foreach (Contact item in contactsList)
                {
                    Contact aContact = item as Contact;

                    if (aContact != null)
                    {
                        TableRow r = new TableRow();

                        TableCell c1 = new TableCell();
                        c1.Text = aContact.Name;
                        r.Controls.Add(c1);

                        TableCell c2 = new TableCell();
                        c2.Text = aContact.Email;
                        r.Controls.Add(c2);


                        TableCell c3 = new TableCell();
                        c3.Text = aContact.Phone;
                        r.Controls.Add(c3);

                        t.Controls.Add(r);
                    }
                }
            }
            return t;
        }
    }
}

Descripción del código

Para habilitar el análisis de los elementos de colección en las etiquetas de un control, el control QuickContacts agrega el atributo ParseChildren(true, "Contacts") al control. El primer argumento (true) de ParseChildrenAttribute especifica que el analizador de páginas debería interpretar el contenido anidado de las etiquetas del control como propiedades, no como controles secundarios. El segundo argumento ("Contacts") proporciona el nombre de la propiedad interna predeterminada. Al especificar el segundo argumento, el contenido de las etiquetas del control debe corresponder sólo a la propiedad interna predeterminada (objetos Contact).

El control QuickContacts incluye asimismo los siguientes atributos en tiempo de diseño que deben aplicarse a una propiedad de colección para la serialización y la persistencia en tiempo de diseño:

  • DesignerSerializationVisibilityAttribute   Si se establece el parámetro Content, se especifica que un diseñador visual debería serializar el contenido de la propiedad. En el ejemplo, la propiedad contiene objetos Contact.

  • PersistenceModeAttribute   Si se pasa el parámetro InnerDefaultProperty, se especifica que un diseñador visual debería conservar la propiedad a la que se aplica el atributo como una propiedad interna predeterminada. Esto significa que un diseñador visual conserva la propiedad dentro de las etiquetas del control. El atributo sólo se puede aplicar a una propiedad, dado que sólo se puede conservar una propiedad en las etiquetas del control. El valor de la propiedad no se ajusta en una etiqueta especial.

El control QuickContacts asocia un editor de colecciones con la propiedad de colección Contacts utilizando EditorAttribute, como en el ejemplo siguiente:

Editor(typeof(ContactCollectionEditor), typeof(UITypeEditor))
Editor(GetType(ContactCollectionEditor), GetType(UITypeEditor))

Si se asocia un editor de colecciones a la propiedad, se habilita el examinador de propiedades en un diseñador visual para abrir un editor de colecciones y agregar elementos Contact. Esto es similar a la interfaz de usuario que se utiliza para editar la propiedad Items de los controles DropDownList o ListBox. El editor de colecciones personalizado utilizado por QuickContacts, ContactCollectionEditor, se describe en Ejemplo de editor de colección.

Por motivos de claridad, el control QuickContacts no define una colección con establecimiento inflexible de tipos; en su lugar, utiliza un objeto ArrayList para su tipo de colección. En general, se debe utilizar una colección con establecimiento inflexible de tipos como tipo de propiedad de colección a fin de que un desarrollador de aplicaciones no pueda agregar tipos arbitrarios a la colección.

Lista de código de la clase Contact

Los atributos en tiempo de diseño del código de la clase Contact son necesarios para la edición de las propiedades y la serialización en tiempo de diseño. El convertidor de tipos ExpandableObjectConverter asociado a la clase Contact (que utiliza el objeto TypeConverterAttribute) permite que el editor de colecciones proporcione la función expandir y contraer en la interfaz de usuario para editar subpropiedades (Name, Email, Phone). Esto es similar a la interfaz de usuario que aparece al editar la propiedad Font de un control Web en el examinador de propiedades de un diseñador visual. El objeto NotifyParentPropertyAttribute (con el argumento de constructor igual a true) aplicado a las propiedades Name, Email y Phone hace que el editor serialice los cambios realizados en estas propiedades en sus propiedades primarias, que son instancias de la clase Contact.

' Contact.vb
' The type of the items in the Contacts collection property 
' in QuickContacts.
Option Strict On
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Web.UI

Namespace Samples.AspNet.VB.Controls
    < _
    TypeConverter(GetType(ExpandableObjectConverter)) _
    > _
    Public Class Contact
        Private _name As String
        Private _email As String
        Private _phone As String

        Public Sub New()
            Me.New(String.Empty, String.Empty, String.Empty)
        End Sub

        Public Sub New(ByVal name As String, _
        ByVal email As String, ByVal phone As String)
            _name = name
            _email = email
            _phone = phone
        End Sub

        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("Name of contact"), _
        NotifyParentProperty(True) _
        > _
        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
            End Set
        End Property

        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("Email address of contact"), _
        NotifyParentProperty(True) _
        > _
        Public Property Email() As String
            Get
                Return _email
            End Get
            Set(ByVal value As String)
                _email = value
            End Set
        End Property


        < _
        Category("Behavior"), _
        DefaultValue(""), _
        Description("Phone number of contact"), _
        NotifyParentProperty(True) _
        > _
        Public Property Phone() As String
            Get
                Return _phone
            End Get
            Set(ByVal value As String)
                _phone = value
            End Set
        End Property
    End Class
End Namespace
// Contact.cs
// The type of the items in the Contacts collection property 
//in QuickContacts.

using System;
using System.Collections;
using System.ComponentModel;
using System.Web.UI;

namespace Samples.AspNet.CS.Controls
{
    [
    TypeConverter(typeof(ExpandableObjectConverter))
    ]
    public class Contact
    {
        private string nameValue;
        private string emailValue;
        private string phoneValue;


        public Contact()
            : this(String.Empty, String.Empty, String.Empty)
        {
        }

        public Contact(string name, string email, string phone)
        {
            nameValue = name;
            emailValue = email;
            phoneValue = phone;
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("Name of contact"),
        NotifyParentProperty(true),
        ]
        public String Name
        {
            get
            {
                return nameValue;
            }
            set
            {
                nameValue = value;
            }
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("Email address of contact"),
        NotifyParentProperty(true)
        ]
        public String Email
        {
            get
            {
                return emailValue;
            }
            set
            {
                emailValue = value;
            }
        }

        [
        Category("Behavior"),
        DefaultValue(""),
        Description("Phone number of contact"),
        NotifyParentProperty(true)
        ]
        public String Phone
        {
            get
            {
                return phoneValue;
            }
            set
            {
                phoneValue = value;
            }
        }
    }
}

Página de prueba del control QuickContacts

En el ejemplo siguiente se muestra una página .aspx que utiliza el control QuickContacts.

<%@ Page Language="VB"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head id="Head1" >
    <title>
      QuickContacts test page
    </title>
  </head>
  <body>
    <form id="Form1" >
      <aspSample:QuickContacts ID="QuickContacts1" Runat="server" 
        BorderStyle="Solid" BorderWidth="1px">
        <aspSample:Contact Name="someone" Email="someone@example.com" 
          Phone="(555) 555-0100"/>
        <aspSample:Contact Name="jae" Email="jae@fourthcoffee.com" 
          Phone="(555) 555-0101"/>
        <aspSample:Contact Name="lene" Email="lene@contoso.com" 
          Phone="(555) 555-0102"/>        
      </aspSample:QuickContacts>
    </form>
  </body>
</html>
<%@ Page Language="C#"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
  <head id="Head1" >
    <title>
      QuickContacts test page
    </title>
  </head>
  <body>
    <form id="Form1" >
      <aspSample:QuickContacts ID="QuickContacts1" Runat="server" 
        BorderStyle="Solid" BorderWidth="1px">
        <aspSample:Contact Name="someone" Email="someone@example.com" 
          Phone="(555) 555-0100"/>
        <aspSample:Contact Name="jae" Email="jae@fourthcoffee.com" 
          Phone="(555) 555-0101"/>
        <aspSample:Contact Name="lene" Email="lene@contoso.com" 
          Phone="(555) 555-0102"/>        
      </aspSample:QuickContacts>
    </form>
  </body>
</html>

Generar y utilizar el ejemplo

Compile el control QuickContacts y la clase Contacts con el editor ContactCollectionEditor incluido en Ejemplo de editor de colección. Debe agregar una referencia al ensamblado System.Design para la compilación.

Para obtener más información sobre la compilación y el uso de los ejemplos de controles personalizados, vea Generar ejemplos de controles de servidor personalizados.

Vea también

Conceptos

Ejemplo de editor de colección

Generar ejemplos de controles de servidor personalizados

Otros recursos

Desarrollar controles de servidor ASP.NET personalizados