共用方式為


複合伺服器控制項範例

下列範例會開發複合控制項 (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>

請參閱

複合控制項和使用者控制項的比較 | 撰寫和呈現的比較 | 反昇事件 | 事件反昇控制項範例