Поделиться через


Пример свойства-коллекции веб-элементов

Обновлен: Ноябрь 2007

В этом примере демонстрируется создание элемента управления с именем QuickContacts, который реализует сохранение на странице свойства-коллекции. В примере используется элемент управления, позволяющий разработчику страницы хранить список адресов книги контактов. Элемент управления QuickContacts предоставляет свойство-коллекцию Contacts, содержащее объекты Contact. Класс Contact имеет свойства Name, Email и Phone.

Элементы Contact из Contacts свойства-коллекции сохраняются внутри тегов элемента управления, как показано в следующем примере:

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

Для ясности элемент управления QuickContacts не реализует управление состоянием для свойства-коллекции. Элементы коллекции считаются добавляемыми декларативно на страницу или, если созданы в коде, то они должны быть созданы заново при обратном запросе. В коммерческом элементе управления будет реализовываться управление состоянием. Дополнительные сведения см. в разделе Управление пользовательскими состояниями серверного элемента управления.

Листинг кода для элемента управления 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;
        }
    }
}

Рассмотрение кода

Чтобы включить разбор элементов коллекции в тегах элемента управления, элемент управления QuickContacts добавляет атрибут ParseChildren(true, "Contacts") к элементу управления. Первый аргумент (true) из ParseChildrenAttribute указывает, что анализатор страницы должен интерпретировать вложенное содержимое внутри тегов элемента управления как свойства, а не как дочерние элементы. Второй аргумент ("Contacts") предоставляет имя внутреннего свойства по умолчанию. При указании второго аргумента содержимое в тегах элемента управления должно соответствовать внутреннему свойству по умолчанию (объекты Contact) и ничему другому.

Элемент управления QuickContacts также включает следующие атрибуты разработки, которые необходимо применить к свойству-коллекции для сериализации при разработке и сохранения:

  • DesignerSerializationVisibilityAttribute. Установка параметра Content указывает, что визуальный конструктор должен сериализовать содержимое свойства. В примере свойство содержит объекты Contact.

  • PersistenceModeAttribute. Передача параметра InnerDefaultProperty указывает, что визуальный конструктор должен сохранять свойство, к которому атрибут применен как внутреннее свойство по умолчанию. Это означает, что визуальный конструктор сохраняет свойство в тегах элемента управления. Атрибут может быть применен только к одному свойству, поскольку только одно свойство может быть сохранено внутри тегов элемента управления. Значение свойства не упаковывается в специальный тег.

Элемент управления QuickContacts связывает редактор коллекции со свойством-коллекцией Contacts с помощью EditorAttribute, как в следующем примере:

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

Сопоставление редактора коллекции со свойством позволяет обозревателю свойств в визуальном конструкторе открыть редактор коллекции для добавления элементов Contact. Он похож на пользовательский интерфейс (UI) для редактирования свойств Items из элементов управления DropDownList или ListBox. Пользовательский редактор коллекции, используемый элементами QuickContacts, ContactCollectionEditor, описан в Пример редактора коллекций.

Для ясности элемент управления QuickContacts не определяет строго типизированную коллекцию и вместо этого использует ArrayList для типа его коллекции. В общем случае следует использовать строго типизированную коллекцию в качестве типа свойства-коллекции так, чтобы разработчик приложения не смог добавить произвольный тип в коллекцию.

Листинг кода класса Contact

Атрибуты времени разработки в коде класса Contact требуются для редактирования свойства и сериализации времени разработки. Преобразователь типов ExpandableObjectConverter, связанный с классом Contact (при помощи TypeConverterAttribute), позволяет редактору коллекции предоставить интерфейс пользователя с возможностью развертки/свертки для редактирования субсвойства (Name, Email, Phone). Это похоже на пользовательский интерфейс при редактировании свойства Font веб-элемента управления в обозревателе визуального конструктора. NotifyParentPropertyAttribute (с аргументом конструктора равным true), применяемый к свойствам Name, Email и Phone, вызывает редактор для сериализации изменений в этих свойствах в их родительское свойство, экземпляр класса 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;
            }
        }
    }
}

Тестовая страница для элемента управления QuickContacts

В следующем примере показана страница .aspx, использующая элемент управления 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" runat="server">
    <title>
      QuickContacts test page
    </title>
  </head>
  <body>
    <form id="Form1" runat="server">
      <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" runat="server">
    <title>
      QuickContacts test page
    </title>
  </head>
  <body>
    <form id="Form1" runat="server">
      <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>

Построение и использование примеров

Скомпилируйте элемент управления QuickContacts и класс Contacts с редактором ContactCollectionEditor, описанным в Пример редактора коллекций. Для компиляции необходимо добавить ссылку на сборку System.Design.

Дополнительные сведения о компиляции и использовании примеров пользовательских элементов управления содержатся в разделе Примеры связывания пользовательского серверного элемента управления.

См. также

Основные понятия

Пример редактора коллекций

Примеры связывания пользовательского серверного элемента управления

Другие ресурсы

Разработка пользовательских серверных элементов управления ASP.NET