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 アセンブリへの参照を追加する必要があります。
カスタム コントロールの例のコンパイルと使用の詳細については、「カスタム サーバー コントロールの例のビルド」を参照してください。