Web コントロールのコレクション プロパティの例

更新 : 2007 年 11 月

この例では、コレクション プロパティのためにページに永続性を実装する QuickContacts というコントロールを作成する方法を示します。ページの開発者は、このサンプル コントロールを使用してアドレス帳の連絡先の一覧を格納できます。QuickContacts コントロールは、Contact オブジェクトを含む Contacts コレクション プロパティを公開します。Contact クラスには、Name、Email、および Phone の各プロパティがあります。

Contacts コレクション プロパティの Contact 項目は、次の例のように、コントロールのタグ内で永続化されています。

<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") 属性を追加します。ParseChildrenAttribute の最初の引数 (true) は、ページ パーサーがコントロールのタグ内の入れ子になったコンテンツを子コントロールとしてではなく、プロパティとして解析する必要があることを指定します。2 番目の引数 ("Contacts") は、内部の既定のプロパティの名前を提供します。2 番目の引数を指定するときは、コントロールのタグ内のコンテンツは内部の既定のプロパティ (Contact オブジェクト) のみに対応している必要があります。

QuickContacts コントロールには、デザイン時のシリアル化と永続化のためにコレクションのプロパティに適用する必要がある次のようなデザイン時属性も含まれます。

  • DesignerSerializationVisibilityAttribute   Content パラメータは、ビジュアル デザイナがプロパティの内容をシリアル化する必要があることを指定します。この例では、プロパティに Contact オブジェクトが含まれます。

  • PersistenceModeAttribute   InnerDefaultProperty パラメータは、属性が内部の既定のプロパティとして適用されるプロパティをビジュアル デザイナが永続化する必要があることを指定します。これは、ビジュアル デザイナがコントロールのタグ内でプロパティを永続化することを意味します。コントロールのタグ内で永続化できるプロパティは 1 つだけのため、この属性を適用できるプロパティは 1 つだけです。このプロパティの値は特別のタグでラップされません。

QuickContacts コントロールは、次の例のように、EditorAttribute を使用してコレクション エディタを Contacts コレクション プロパティに関連付けます。

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

コレクション エディタをプロパティに関連付けると、ビジュアル デザイナのプロパティ ブラウザはコレクション エディタを開いて Contact 項目を追加できます。これは、DropDownList コントロールまたは ListBox コントロールの Items プロパティを編集するためのユーザー インターフェイス (UI) に似ています。QuickContacts が使用するカスタム コレクション エディタ (ContactCollectionEditor) については、「コレクション エディタの例」を参照してください。

簡略化のために、QuickContacts コントロールは、厳密に型指定されたコレクションを定義せずに、ArrayList コレクション型を使用します。一般に、アプリケーション開発者が任意の型をコレクションに追加できないように、コレクション プロパティの型として厳密に型指定されたコレクションを使用する必要があります。

Contact クラスのコード リスト

プロパティの編集およびデザイン時のシリアル化には、Contact クラスのコードにデザイン時の属性が必要です。Contact クラスに関連付けられている ExpandableObjectConverter 型コンバータによって (TypeConverterAttribute を使用)、コレクション エディタはサブプロパティ (Name、Email、Phone) の編集に展開/折りたたみのユーザー インターフェイスを提供します。これはビジュアル デザイナのプロパティ ブラウザで Web コントロールの Font プロパティを編集する際のユーザー インターフェイスに似ています。Name、Email、および Phone の各プロパティに適用された NotifyParentPropertyAttribute (コンストラクタ引数を true に設定) によって、エディタはこれらのプロパティに対する変更を親プロパティである 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 コントロールのテスト ページ

QuickContacts コントロールを使用する .aspx ページの例を次に示します。

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

例のビルドと使用

コレクション エディタの例」に記載されている ContactCollectionEditor エディタを使用して、QuickContacts コントロールと Contacts クラスをコンパイルします。コンパイルには System.Design アセンブリへの参照を追加する必要があります。

カスタム コントロールの例のコンパイルと使用の詳細については、「カスタム サーバー コントロールの例のビルド」を参照してください。

参照

概念

コレクション エディタの例

カスタム サーバー コントロールの例のビルド

その他の技術情報

ASP.NET カスタム サーバー コントロールの開発