Custom server controls provide a way of encapsulating server-side code with client-side HTML and scripting into a single logical unit. They allow you to develop a reusable object with a public interface consisting of properties, methods, and events that can be used by dragging and dropping the object when doing design with a visual designer. Custom Controls and User Controls.NET provides for two types of developer-created server controls: custom server controls and user controls. This chapter will focus on the custom server controls, but I think it is important to understand the difference between the two types of server controls and when each should be used. User controls are in many ways much easier to develop than custom controls. User controls can be designed in Visual Studio .NET using the visual designer, while the visual portion of custom controls must be coded entirely by hand. Despite this, custom controls are in many ways superior to user controls and have the following advantages:
The only real advantages user controls have over custom controls are that they are easier to implement, and they are potentially easier to make changes to. The following recommendation should be carefully considered.
RECOMMENDED PRACTICE: One should use a user control when reuse is only across a project (it's a time-constraint thing). When the control is used in a second project, take a few hours and turn it into a custom control. User controls are generally used when you need a control that is specific to a given application and will probably be used only a few times. Custom controls are used when you need a control to be used across many applications. Because for this chapter we are developing an application that is intended to be used across many applications, we will develop it as a custom server control. Custom Server Control BasicsEven if you've never created a server control, server controls should not be new because you will have used the ones provided as part of the .NET Framework. What may not be clear is that there are two basic types of custom control. There are render controls, which produce their output by writing HTML directly to an output stream, and there are composite controls, which produce their output by keeping a collection of child controls and calling the Render() method of each of its child controls in turn when it needs to render itself. The basics of creating either a render or a composite control are the same. Creating a custom control requires that you do two things:
The method you choose to override depends on what type of server control you are creating. If you are creating a composite control, you would normally override the CreateChildControls() method. If you are creating a render control, you would normally override the Render() method. It is also possible to create a hybrid control by overriding both the CreateChildControl() method and the Render() method. Render ControlsA render control is a control that does not contain any other server controls and outputs only HTML. Implementing a control this way usually results in better performance than a composite control provides, but it is harder to implement extended functionality. This control is defined by overriding the WebControl base class's Render() method. Listing 15.1 shows a simple render control. Listing 15.1 Simple Render ControlImports System.ComponentModel Imports System.Web.UI Public Class WebCustomControl1 Inherits System.Web.UI.WebControls.WebControl Dim _text As String Property [Text]() As String Get Return _text End Get Set(ByVal Value As String) _text = Value End Set End Property Protected Overrides Sub Render(ByVal output _ As System.Web.UI.HtmlTextWriter) output.Write([Text]) End Sub End Class Most applications will use composite controls rather then render controls because you can use the additional functionality of an existing server control without having to re-implement the details of the control. This is especially true because the .NET platform includes server controls for so many basic controls. For this reason, render controls will not be discussed in detail, and the remainder of the chapter will concentrate on composite controls. Composite ControlsBy far the more common in my experience, composite controls allow you to use the functionality of existing server controls to make up your control. To create a composite control, you need to override the CreateChild Controls() method of the WebControl class and add all of the contained controls to the Controls collection. Text or HTML can be added by using a LiteralControl. Listing 15.2 shows a simple composite control with a single label as a contained control. The output would be the same as that for the render control example. Listing 15.2 Simple Composite ControlImports System.ComponentModel Imports System.Web.UI Public Class WebCustomControl1 Inherits System.Web.UI.WebControls.WebControl Dim _text As String Property [Text]() As String Get Return _text End Get Set(ByVal Value As String) _text = Value End Set End Property Protected Overrides Sub CreateChildControls() Dim label As New Label label.Text = Me.Text Me.Controls.Add(label) End Sub End Class INamingContainer InterfaceMany times you need to have several instances of a control you created on the same page. This can be a problem if you are assigning unique IDs to the controls contained in a composite control. To get around this problem, the .NET Framework has defined an interface called INamingContainer. This is a marker interface that has no methods or properties that need to be implemented. Controls that implement this interface will automatically concatenate the ID of the child control with the ID of the parent control to generate unique IDs for all controls on the page. Following is an example of how to implement this interface. C#public class MyControl : WebControl,INamingContainer { // Class implementation goes here }VB Public Class WebCustomControl1 Inherits System.Web.UI.WebControls.WebControl Implements INamingContainer 'Class implementation goes here End Class You will also need to implement this interface if you wish to handle any events of contained server controls. Handling Events from Contained ControlsComposite controls allow you to easily handle the events of contained controls and generate events for your control. It is important to note here that you must implement the INamingContainer interface as described in the preceding section. Event handling is a straightforward two-step process. First, define a function to handle the event. Second, add the event handler to the event to be handled. Following is an example of how to handle an event for a contained control. C#Button objButton=new Button(); objButton.Text="Press Me"; objButton.; objButton.Click+=new EventHandler(OnButton_Click); Controls.Add(objButton);VB Dim objButton AS new Button() objButton.Text="Press Me" objButton. AddHandler objButton.Click,AddressOf OnButton_Click Controls.Add(objButton) The event-handler function needs to be defined using the .NET standard format for event handlers. C#private void OnButton_Click(Object sender, EventArgs e) { // Event handling code goes here }VB Private Sub OnButton_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles Button.Click ' Event handling code goes here End Sub Other than what has been shown, the complexity of the composite control lies mainly in what you are trying to do. Because of this, we are going to show how controls are created by creating the controls necessary for this chapter's example. |