複合伺服器控制項範例
下列範例會開發複合控制項 (Composite
),它結合了四個 ASP.NET 伺服器控制項:兩個 Textbox 控制項、一個 Label 控制項和一個 Button 控制項。當按一下其子 Button 控制項時,Composite
會檢查輸入文字方塊的兩個數字的總和是否等於指定數字 (定義為自訂屬性),並引發自訂事件。它也將其子 Label 控制項公開為最上層屬性。
注意,複合控制項的子控制項是封裝的。預設的情況下,它們在父控制項之外是不可見的 (網頁開發人員可能會使用父控制項的 Controls 集合嘗試存取子控制項,但因為其間有常值 (Literal) 控制項介入,取得特定子控制項的索引可能很困難)。
複合控制項可以選擇是否要公開子控制項為屬性,也可以選擇其子控制項的哪些屬性和事件要公開為最上層屬性和事件。當複合控制項從其子控制項的那些屬性來合成屬性時,它只是委派 (Delegate) 給子控制項,如下列範例所示。
// 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
公開下列公用 (Public) 屬性。
Number
允許網頁開發人員指定數字的自訂屬性。
Text
從子 Label 控制項的 Text 屬性中合成的屬性。
Composite
公開下列自訂事件。
Check
Composite
檢查文字方塊中的兩個數字的總和是否等於Number
值時所引發的自訂事件。Check
事件需要自訂事件委派CheckEventHandler
,和事件資料CheckEventArgs
的對應類別。如需定義自訂事件的詳細資訊,請參閱定義事件。
也請注意 Composite
控制項的下列特性。
Composite
使用 CreateChildControls 方法建立其子控制項,而不是使用 OnInit 或其建構函式 (Constructor)。Composite
不公開其 Button 子控制項的 Click 事件。它反而處理 Click 事件,並引發自訂事件Check
。如果複合控制項處理其子控制項引發的事件,它必須在 CreateChildControls 中發送事件處理常式。Composite
實作 INamingContainer,將回傳事件轉送至其子 Button 控制項。
注意,您可以將事件從子控制項向上反昇至容器,並將它們公開為容器的最上層事件。如需詳細資訊,請參閱反昇事件和事件反昇控制項範例。
複合控制項範例的程式碼如下。若要建置範例,請參閱伺服器控制項範例中的說明。
// 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>
請參閱
複合控制項和使用者控制項的比較 | 撰寫和呈現的比較 | 反昇事件 | 事件反昇控制項範例