複合サーバー コントロールのサンプル
ここで示す 4 つのサンプルでは、ASP.NET サーバー コントロール (2 つの Textbox コントロール、1 つの Label コントロール、1 つの Button コントロール) を組み合わせた複合コントロール (Composite
) を作成します。複合コントロールの Button 子コントロールがクリックされると、テキスト ボックスに入力された 2 つの数値の合計が、カスタム プロパティとして定義されている指定の数値と等しいかどうかを Composite
がチェックし、カスタム イベントを発生させます。また、Label 子コントロールの Text プロパティが最上位レベルのプロパティとして公開されています。
複合コントロールの子コントロールがカプセル化されていることに注意してください。既定では、親の外部では子コントロールは非表示になります。ページ開発者は、親コントロールの Controls コレクションを使用して子コントロールにアクセスしてみることができますが、リテラル コントロールも含まれているため、特定の子コントロールのインデックスを取得することは難しい場合があります。
複合コントロールでは、子コントロールをプロパティとして公開するかどうかを選択できます。また、子コントロールのどのプロパティおよびイベントを最上位レベルのプロパティおよびイベントとして公開するかも選択できます。複合コントロールが子コントロールのプロパティから合成したプロパティを使用している場合は、次の例に示すように、単に子コントロールに処理が渡されます。
// Delegate to label, which is an instance of
// System.Web.UI.WebControls.Label.
public string Text
{
get
{
EnsureChildControls();
return label.Text;
}
set
{
EnsureChildControls();
label.Text = value;
}
}
Composite
が公開するパブリック プロパティを次に示します。
Number
ページ開発者が数値を指定できるようにするカスタム プロパティです。
Text
Label 子コントロールの Text プロパティから合成されたプロパティです。
Composite
が公開するカスタム イベントを次に示します。
Check
テキスト ボックスの 2 つの数値の合計が
Number
の値と等しいかどうかをComposite
がチェックするときに発生するカスタム イベントです。Check
イベントには、CheckEventHandler
カスタム イベント デリゲートと、対応するイベント データのCheckEventArgs
クラスが必要です。カスタム イベントの定義の詳細については、「イベントの定義」を参照してください。
Composite
コントロールの次の機能にも注意してください。
Composite
は、OnInit メソッドやそのコンストラクタではなく、CreateChildControls メソッドの中で子コントロールを作成します。Composite
は、Button 子コントロールの Click イベントは公開しません。代わりに Click イベントを処理して、Check
カスタム イベントを発生させます。複合コントロールは、子コントロールが発生させたイベントを処理する場合は、CreateChildControls 内でイベント ハンドラを関連付ける必要があります。- Button 子コントロールへポストバック イベントをルーティングするために、
Composite
は INamingContainer を実装します。
子コントロールからのイベントをコンテナまでバブルし、コンテナの最上位レベルのイベントとして公開できます。詳細については、「イベントのバブル」および「イベント バブル コントロールのサンプル」を参照してください。
複合コントロールのサンプル コードを次に示します。このサンプルをビルドする方法については、「サーバー コントロールのサンプル」の手順を参照してください。
// Composite.cs.
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomControls
{
public class Composite : Control, INamingContainer
{
private int number = 100;
private Label label;
public int Number
{
get
{
return number;
}
set
{
number = value;
}
}
private int Sum
{
get
{
EnsureChildControls();
return Int32.Parse(((TextBox)Controls[1]).Text) +
Int32.Parse(((TextBox)Controls[4]).Text);
}
}
public string Text
{
get
{
EnsureChildControls();
return label.Text;
}
set
{
EnsureChildControls();
label.Text = value;
}
}
public event CheckEventHandler Check;
protected virtual void OnCheck(CheckEventArgs ce)
{
if (Check != null)
{
Check(this,ce);
}
}
protected override void CreateChildControls()
{
Controls.Add(new LiteralControl("<h3>Enter a number : "));
TextBox box1 = new TextBox();
box1.Text = "0";
Controls.Add(box1);
Controls.Add(new LiteralControl("</h3>"));
Controls.Add(new LiteralControl("<h3>Enter another number : "));
TextBox box2 = new TextBox();
box2.Text = "0";
Controls.Add(box2);
Controls.Add(new LiteralControl("</h3>"));
Button button1 = new Button();
button1.Text = "Submit";
Controls.Add(new LiteralControl("<br>"));
Controls.Add(button1);
button1.Click += new EventHandler(this.ButtonClicked);
Controls.Add(new LiteralControl("<br><br>"));
label = new Label();
label.Height = 50;
label.Width = 500;
label.Text = "Click the button to see if you won.";
Controls.Add(label);
}
protected override void OnPreRender(EventArgs e)
{
((TextBox)Controls[1]).Text = "0";
((TextBox)Controls[4]).Text = "0";
}
private void ButtonClicked(Object sender, EventArgs e)
{
OnCheck(new CheckEventArgs(Sum - Number));
}
}
}
// CheckEvent.cs.
// Contains the code for the custom event data class CheckEventArgs.
// Also defines the event handler for the Check event.
using System;
namespace CustomControls
{
public class CheckEventArgs : EventArgs
{
private bool match = false;
public CheckEventArgs (int difference)
{
if (difference == 0)
{
match = true;
}
}
public bool Match
{
get
{
return match;
}
}
}
public delegate void CheckEventHandler(object sender, CheckEventArgs ce);
}
[Visual Basic]
' Composite.vb.
Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace CustomControls
Public Class Composite
Inherits Control
Implements INamingContainer
Private _number As Integer = 100
Private label As Label
Public Property Number() As Integer
Get
Return _number
End Get
Set
_number = value
End Set
End Property
Private ReadOnly Property Sum() As Integer
Get
EnsureChildControls()
Return Int32.Parse(CType(Controls(1), TextBox).Text) + Int32.Parse(CType(Controls(4), TextBox).Text)
End Get
End Property
Public Property Text() As String
Get
EnsureChildControls()
Return label.Text
End Get
Set
EnsureChildControls()
label.Text = value
End Set
End Property
Public Event Check As CheckEventHandler
Protected Overridable Sub OnCheck(ce As CheckEventArgs)
RaiseEvent Check(Me, ce)
End Sub
Protected Overrides Sub CreateChildControls()
Controls.Add(New LiteralControl("<h3>Enter a number : "))
Dim box1 As New TextBox()
box1.Text = "0"
Controls.Add(box1)
Controls.Add(New LiteralControl("</h3>"))
Controls.Add(New LiteralControl("<h3>Enter another number : "))
Dim box2 As New TextBox()
box2.Text = "0"
Controls.Add(box2)
Controls.Add(New LiteralControl("</h3>"))
Dim button1 As New Button()
button1.Text = "Submit"
Controls.Add(New LiteralControl("<br>"))
Controls.Add(button1)
AddHandler button1.Click, AddressOf Me.ButtonClicked
Controls.Add(New LiteralControl("<br><br>"))
label = New Label()
label.Height = Unit.Pixel(50)
label.Width = Unit.Pixel(500)
label.Text = "Click the button to see if you won."
Controls.Add(label)
End Sub
Protected Overrides Sub OnPreRender(e As EventArgs)
CType(Controls(1), TextBox).Text = "0"
CType(Controls(4), TextBox).Text = "0"
End Sub
Private Sub ButtonClicked(sender As [Object], e As EventArgs)
OnCheck(New CheckEventArgs(Sum - Number))
End Sub
End Class
End Namespace
' CheckEvent.vb
' Contains the code for the custom event data class CheckEventArgs.
' Also defines the event handler for the Check event.
Imports System
Namespace CustomControls
Public Class CheckEventArgs
Inherits EventArgs
Private _match As Boolean = False
Public Sub New(difference As Integer)
If difference = 0 Then
_match = True
End If
End Sub
Public ReadOnly Property Match() As Boolean
Get
Return _match
End Get
End Property
End Class
Public Delegate Sub CheckEventHandler(sender As Object, ce As CheckEventArgs)
End Namespace
ページでの複合コントロールの使用
ASP.NET ページで Composite
複合コントロールを使用する例を次に示します。
<%@ Register TagPrefix="Custom" Namespace="CustomControls" Assembly = "CustomControls" %>
<html>
<script language="VB" runat=server>
Private Sub Sum_Checked(sender As Object, e As CheckEventArgs)
If e.Match = True Then
Composite.Text = "<h2> You won a million dollars.!!!! </h2>"
Else
Composite.Text = "Sorry, try again. The numbers you entered don't add up to" _
& " the hidden number."
End If
End Sub
</script>
<body>
<h1> The Mystery Sum Game </h1><br>
<form runat=server>
<Custom:Composite id = "Composite" OnCheck = "Sum_Checked" Number= "10" runat = server/>
</form>
</body>
</html>
参照
複合コントロールとユーザー コントロール | コンポジションとレンダリング | イベントのバブル | イベント バブル コントロールのサンプル