8.3 Composite Controls


Many controls contain other controls as part of their definition ”these are termed composite controls. By embedding other controls within them, custom controls can be used to define " chunks " of forms that can potentially be reused from many different pages, complete with their own properties, events, and methods . Composite controls are built by creating child controls and adding them to the Controls collection of the parent control. All creation of child controls should take place in an override of the virtual function CreateChildControls . This function is inherited from the Control base class and is called at the correct time to create child controls (after the Load event, just before rendering).

8.3.1 Creating Child Controls

Listing 8-30 shows a simple composite control that implements a calculator by using three TextBox controls, a Button control, and some Literal Control s intermingled. A LiteralControl is a simple control that renders its Text property and is especially useful when building composite controls for properly laying out the child controls. This control also shows an example of hooking up an event handler to a child control.

Listing 8-30 Composite Control Example
 Public Class CalcComposite   Inherits Control   Implements INamingContainer     Private _operand1 As TextBox     Private _operand2 As TextBox     Private _result   As TextBox     Private Sub OnCalculate(sender As Object, _                             e As EventArgs)       Dim res As Integer       res = Convert.ToInt32(_operand1.Text) + _             Convert.ToInt32(_operand2.Text)       _result.Text = res.ToString()     End Sub     Public ReadOnly Property Result As Integer       Get         Return Convert.ToInt32(_result.Text)       End Get     End Property     Protected Overrides Sub CreateChildControls()       _operand1 = new TextBox()       _operand1.ID = "Op1"       _operand2 = new TextBox()       _operand2.ID = "Op2"       _result   = new TextBox()       _result.ID = "Res"       Controls.Add(_operand1)       Controls.Add(new LiteralControl(" + "))       Controls.Add(_operand2)       Controls.Add(new LiteralControl(" = "))       Controls.Add(_result)       Controls.Add(new LiteralControl("<br/>"))       Dim calculate As Button = new Button()       calculate.Text = "Calculate"       AddHandler calculate.Click, _                  New EventHandler(AddressOf Me.OnCalculate)       Controls.Add(calculate)     End Sub   End Class 

Notice also that the control shown in Listing 8-30 implements the INamingContainer interface. This is a marker interface (one with no methods) that indicates to the containing page that this control has child controls that may need to be in a separate namespace. If there is more than one instance of a composite control on a given page, it is important that the child controls of each composite control not have ID clashes . Anytime you have child controls in a custom control, you should be sure to add support for INamingContainer to avoid ID clashes in the rendered HTML.

You may find that in your composite control, you would like to manipulate some of your child controls during the Load event of your control. The CreateChildControls method is not called until after the Load event has fired , however, so if you attempt to access any child controls within a Load handler, you will find none. To guarantee that your child controls have been created, you can always call EnsureChildControls() . This function checks to see if the CreateChildControls function has been called yet (by checking the ChildControlsCreated Boolean), and if not, calls it for you. For example, the composite control shown in Listing 8-31 explicitly calls EnsureChildControls from within its Load handler before it tries to set one of the children's values.

Listing 8-31 Calling EnsureChildControls
 Public Class CalcComposite   Inherits Control   Implements INamingContainer   Private _operand1 As TextBox   Private _operand2 As TextBox   Private _result   As TextBox   Protected Sub Page_Load(src As Object, e As EventArgs)     EnsureChildControls()     _operand1.Text = "41"   End Sub   Protected Overrides Sub CreateChildControls()     _operand1 = new TextBox()     _operand2 = new TextBox()     _result   = new TextBox()     '...   End Sub End Class 

With a composite control, it may also be useful to retrieve a child control dynamically. This is easily done with the FindControl method, which takes the string identifier of the control and returns a reference to the control.

8.3.2 Custom Events

For a custom control to truly provide all the attributes of standard Web controls, it must be able to define and propagate events. You define events in a custom control by adding a public event data member of delegate type EventHandler . A client then attaches a method to the event handler, and it is up to the control to invoke that method whenever the event logically occurs. Listing 8-32 shows a modified version of our CalcComposite control with a custom event added. Note that it declares a public EventHandler member called MagicNumber to which clients can hook delegates. In our example, the EventHandler is invoked whenever the user calculates the value 42 with the calculator. Listing 8-33 shows a sample .aspx page that traps the MagicNumber event and populates a label in response.

Listing 8-32 Control with Custom Event Example
 Public Class CalcComposite   Inherits Control   Implements INamingContainer     ' other members not shown   Public Event MagicNumber As EventHandler   Private Sub OnCalculate(sender As Object, _                           e As EventArgs)     Dim res As Integer     res = Convert.ToInt32(_operand1.Text) + _               Convert.ToInt32(_operand2.Text)     _result.Text = res.ToString()     If res = 42 Then       RaiseEvent MagicNumber(Me, EventArgs.Empty)     End If   End Sub   Protected Overrides Sub CreateChildControls()     'Other control creation not shown...     Dim calculate As Button = new Button()     calculate.Text = "Calculate"     AddHandler calculate.Click, _                New EventHandler(AddressOf Me.OnCalculate)     Controls.Add(calculate)   End Sub End Class 
Listing 8-33 Sample Custom Event Client
 <%@ Page Language="VB" %> <%@ Register TagPrefix="eadn"              Namespace="EssentialAspDotNet.CustomControls"              Assembly="CalcComposite" %> <html> <script runat=server> Private Sub MyCtrl_OnMagicNumber(src As Object, _                                  e As EventArgs)   MagicNumberLabel.Text = "Magic number calculated!!" End Sub </script> <body>   <form runat=server>     <asp:Label id=MagicNumberLabel runat=server />     <eadn:SimpleComposite id="MyCtrl"        OnMagicNumber="MyCtrl_OnMagicNumber" runat=server />   </form> </body> </html> 


Essential ASP.NET with Examples in Visual Basic .NET
Essential ASP.NET with Examples in Visual Basic .NET
ISBN: 0201760398
EAN: 2147483647
Year: 2003
Pages: 94
Authors: Fritz Onion

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net