Getting Started
  Introduction
  What is ASP.NET?
  Language Support

ASP.NET Web Forms
  Introducing Web Forms
  Working with Server Controls
  Applying Styles to Controls
  Server Control Form Validation
  Web Forms User Controls
  Data Binding Server Controls
  Server-Side Data Access
  Data Access and Customization
  Working with Business Objects
  Authoring Custom Controls
  Web Forms Controls Reference
  Web Forms Syntax Reference

ASP.NET Web Services
  Introducing Web Services
  Writing a Simple Web Service
  Web Service Type Marshalling
  Using Data in Web Services
  Using Objects and Intrinsics
  The WebService Behavior
  HTML Pattern Matching

ASP.NET Web Applications
  Application Overview
  Using the Global.asax File
  Managing Application State
  HttpHandlers and Factories

Cache Services
  Caching Overview
  Page Output Caching
  Page Fragment Caching
  Page Data Caching

Configuration
  Configuration Overview
  Configuration File Format
  Retrieving Configuration

Deployment
  Deploying Applications
  Using the Process Model
  Handling Errors

Security
  Security Overview
  Authentication & Authorization
  Windows-based Authentication
  Forms-based Authentication
  Authorizing Users and Roles
  User Account Impersonation
  Security and WebServices

Localization
  Internationalization Overview
  Setting Culture and Encoding
  Localizing ASP.NET Applications
  Working with Resource Files

Tracing
  Tracing Overview
  Trace Logging to Page Output
  Application-level Trace Logging

Debugging
  The SDK Debugger

Performance
  Performance Overview
  Performance Tuning Tips
  Measuring Performance

ASP to ASP.NET Migration
  Migration Overview
  Syntax and Semantics
  Language Compatibility
  COM Interoperability
  Transactions

Sample Applications
  A Personalized Portal
  An E-Commerce Storefront
  A Class Browser Application
  IBuySpy.com

  Get URL for this page

Authoring Custom Controls


This section of the QuickStart demonstrates how advanced developers can write their own ASP.NET server controls that work within the ASP.NET page framework. By writing your own custom ASP.NET server controls, you can encapsulate custom user interface and other functionality in controls that can be reused on ASP.NET pages. The QuickStart provides an introduction to authoring custom controls through hands-on examples. For more information about control authoring, see Developing ASP.NET Server Controls in the Microsoft .NET Framework SDK documentation.

Note: The controls described in this section might not work correctly at design time in a forms designer such as Microsoft Visual Studio .NET, although they work properly at run time on ASP.NET pages. To work in a designer, a control needs to apply design-time attributes not described here. For details about the design-time attributes you need to apply, see Design-Time Attributes for Components in the SDK documentation.

Developing a Simple Custom Control

It is easy to start authoring your own ASP.NET server controls. To create a simple custom control, all you have to do is to define a class that derives from System.Web.UI.Control and override its Render method. The Render method takes one argument of type System.Web.UI.HtmlTextWriter. The HTML that your control wants to send to the client is passed as a string argument to the Write method of HtmlTextWriter.

The following example demonstrates a simple control that renders a message string.

 
VB Simple.aspx

[Run Sample] | [View Source]


Defining Simple Properties

Properties are like "smart" fields that have accessor methods. You should expose properties instead of public fields from your controls because properties allow data hiding, can be versioned, and are supported by visual designers. Properties have get/set accessor methods that set and retrieve properties, and allow additional program logic to be performed if needed.

The following sample shows how to add simple properties that correspond to primitive data types such as integer, Boolean, and string. The sample defines three properties - Message is of type string, MessageSize is of type enumeration, and Iterations is of type integer. Note the page syntax for setting simple and enumeration properties.

 
VB SimpleProperty.aspx

[Run Sample] | [View Source]


Defining Class Properties

If a class A has a property whose type is class B, then the properties of B (if any) are called subproperties of A. The following sample defines a custom control SimpleSubProperty that has a property of type Format. Format is a class that has two primitive properties - Color and Size, which in turn become subproperties of SimpleSubProperty.

 
VB SimpleSubProperty.aspx

[Run Sample] | [View Source]

Note that ASP.NET has a special syntax for setting subproperties. The following code example shows how to declaratively set the Format.Color and Format.Size subproperties on SimpleSubProperty. The "-" syntax denotes a subproperty.

<SimpleControlSamples:SimpleSubProperty Message="Hello There" Format-Color="red" Format-Size="3" runat=server/>


Retrieving Inner Content

Every control has a Controls property that it inherits from System.Web.UI.Control. This is a collection property that denotes the child controls (if any) of a control. If a control is not marked with the ParseChildrenAttribute or marked with ParseChildrenAttribute(ChildrenAsProperties = false), the ASP.NET page framework applies the following parsing logic when the control is used declarartively on a page. If the parser encounters nested controls within the control's tags, it creates instances of them and adds them to the Controls property of the control. Literal text between tags is added as a LiteralControl. Any other nested elements generate a parser error.

The following sample shows a custom control, SimpleInnerContent, that renders text added between its tags by checking if a LiteralControl has been added to its Controls collection. If so, it retrieves the Text property of the LiteralControl, and appends it to its output string.

 
VB SimpleInnerContent.aspx

[Run Sample] | [View Source]

Note: If your custom control derives from WebControl, it will not have the parsing logic described in the sample, because WebControl is marked with ParseChildrenAttribute(ChildrenAsProperties = true), which results in a different parsing logic. For more information about the ParseChildrenAttribute, see the SDK documentation.


Developing a Composite Control

You can author new controls by combining existing controls using class composition. Composite controls are equivalent to user controls that are authored using ASP.NET page syntax. The main difference between user controls and composite controls is that user controls are persisted as .ascx text files, whereas composite controls are compiled and persisted in assemblies.

The key steps in developing a composite control are:

You do not have to override the Render method because child controls provide rendering logic. You can expose properties that synthesize properties of the child controls.

The following sample defines a composite control, Composition1, that combines a System.Web.UI.LiteralControl and a System.Web.UI WebControls.TextBox. Composition1 exposes a custom property, Value, of type integer, that maps to the Text property of TextBox.

 
VB Composition1.aspx

[Run Sample] | [View Source]


Handling Events in a Composite Control

A composite control can handle events raised by its child controls. This is accomplished by providing event handling methods and attaching delegates to the events raised by the child controls.

The following sample shows a composite control, Composition2, that adds two button controls (named Add and Subtract) to the composite control from the previous example and provides event handling methods for the Click events of the buttons. These methods increment and decrement the Value property of Composition2. The CreateChildControls method of Composition2 creates instances of event handlers (delegates) that reference these methods, and attaches the delegates to the Click events of the Button instances. The end result is a control that does its own event handling - when the Add button is clicked, the value in the text box is incremented, and when the Subtract button is clicked, the value is decremented.

 
VB Composition2.aspx

[Run Sample] | [View Source]


Raising Custom Events from a Composite Control

A composite control can define custom events that it raises in response to events raised by its child controls.

The following example shows a composite control, Composition3, that raises a custom event, Change, in response to the TextChanged event of the TextBox child control.

This is accomplished as follows:

The Change event can be handled by a page that hosts the control, as shown in the following sample. In the sample, the page provides an event-handling method for the Change event that sets the Value property to zero if the number entered by the user is negative.

 
VB Composition3.aspx

[Run Sample] | [View Source]


Maintaining State

Every Web Forms control has a State property (inherited from Control) that enables it to participate in State management. The type of State is Sytem.Web.UI.StateBag, which is a data structure equivalent to a hashtable. A control can save data in State as key/value pairs. State is persisted to a string variable by the ASP.NET page framework and makes a round trip to the client as a hidden variable. Upon postback, the page framework parses the input string from the hidden variable and populates the State property of each control in the control hierarchy of a page. A control can restore its state (set properties and fields to their values before postback) using the State property. Control developers should be aware that there is a performance overhead in sending data by round trip to the client, and be judicious about what they save in State.

The following code example shows a property that is saved in State.

VB

The following sample shows a custom control, Label, that has two properties, Text and FontSize, that are saved in State. The ASP.NET page that uses Label contains buttons that have event handlers to increase the font size of the text in Label when a button is clicked. Thus the font size increases every time a button is clicked. This is possible only due to state management - Label needs to know what the font size was before postback in order to render the next larger font size after postback.

 
VB Label.aspx

[Run Sample] | [View Source]


Developing a Custom (Non-Composite) Control that Handles Postback Data

You authored a simple custom control at the beginning of this QuickStart. The following example demonstrates a custom control that does something more meaningful - it renders an input box, and reads in data entered by the user. A control that examines postback (input) data must implement the System.Web.UI.IPostBackDataHandler interface. This signals to the ASP.NET page framework that a control should participate in postback data handling. The page framework passes input data to the LoadPostData method of this interface as key/value pairs. In its implementation of this method, the control can examine the input data and update its properties as shown below.

VB

The following sample defines a custom control, NonComposition1, that implements IPostBackDataHandler and has one property, Value. The control renders an HTML input box whose text attribute is the string representation of Value. The property is set by examining postback input data. The page that uses NonComposition1 also has two buttons that have event handlers to increment and decrement the Value property of NonComposition1.

 
VB NonComposition1.aspx

[Run Sample] | [View Source]


Generating Client-side JavaScript for Custom Postback

If a control wants to capture postback events (form submissions from a client), it must implement the System.Web.UI.IPostBackEventHandler interface. This signals to the ASP.NET page framework that a control wants to be notified of a postback event. The RaisePostBackEvent method allows the control to handle the event, and to raise other events. Additionally, the ASP.NET page framework has a custom event architecture that allows a control to generate client-side JavaScript that initiates custom postback. Normally, postback is initiated by only a few elements such as a Submit button or an Image button. However, by emitting client-side JavaScript, a control can also initiate postback from other HTML elements.

The following example defines a custom control, NonComposition2, that builds on the previous example, NonComposition1. In addition to the interface provided by NonComposition1, it renders two HtmlButtons that generate client-side JavaScript to cause postback when clicked. The name attributes of these buttons are Add and Subtract. The name attribute is passed as a string argument to RaisePostBackEvent by the page framework. NonComposition2 implements RaisePostBackEvent to increment the Value property if Add is clicked and to decrement Value if Subtract is clicked, as shown below.

VB

The user interface that is presented to the client is identical to that in the previous example; however, the entire UI is rendered by one custom control that also handles the postback events. The page developer can simply add NonComposition2 to the page, without providing any event handling logic. The following sample presents this code in action.

 
VB NonComposition2.aspx

[Run Sample] | [View Source]


Developing a Templated Control

The ASP.NET page framework allows control developers to author controls that separate the user interface from the control logic through the use of templates. Page developers can customize the presentation of the control by providing the UI as parameters between template tags.

Templated controls have one or more properties of type System.Web.UI.ITemplate, as shown in the following example.

VB

The attribute (in square brackets above) specifies the type of the container (parent) control.

The ITemplate interface has one method, InstantiateIn, that creates a control instance dynamically. This is invoked on the ITemplate property in the CreateChildControls method, as shown in the following example.


Protected Overrides Sub CreateChildControls()
    If MessageTemplate <> Null Then
        MessageTemplate.InstantiateIn(Me)
    End if
    ...
End Sub
VB

The following sample shows a simple templated control and an ASP.NET page that uses it.

 
VB Template1.aspx

[Run Sample] | [View Source]


Developing a Templated Databound Control

The following sample shows a more complex use of templates to create a databound control. The Repeater control defined in this example is similar to the System.Web.UI.WebControls.Repeater control.

 
VB Repeater1.aspx

[Run Sample] | [View Source]

The following sample modifies the preceding sample so that a page consumer can walk its Items collection during postback to pull out values from it.

 
VB Repeater2.aspx

[Run Sample] | [View Source]


Overriding Control Parsing

As you saw in Retrieving Inner Content , if a control A has nested controls within its control tags on a page, the page parser adds instances of those controls to A's Controls collection. This is done by invoking the AddSubParsedObject method of A. Every control inherits this method from Control; the default implementation simply inserts a child control into the control hierarchy tree. A control can override the default parsing logic by overriding the AddSubParsedObject method. Note that this discussion is somewhat simplified; more details are given in the next example.

The following sample defines a custom control, CustomParse1, that overrides the default parsing logic. When a child control of a certain type is parsed, it adds it to a collection. The rendering logic of CustomParse1 is based on the number of items in that collection. A simple custom control, Item, is also defined in the sample.

 
VB CustomParse1.aspx

[Run Sample] | [View Source]

Note: If your custom control derives from WebControl, it will not have the parsing logic described in the sample, because WebControl is marked with ParseChildrenAttribute(ChildrenAsProperties = true), which results in a different parsing logic. For more information about the ParseChildrenAttribute, see the SDK documentation. The Retrieving Inner Content topic also describes this issue in more detail.


Defining a Custom Control Builder

The ASP.NET page framework uses classes called control builders to process the declarations within control tags on a page. Every Web Forms control is associated with a default control builder class, System.Web.UI.ControlBuilder. The default control builder adds a child control to the Controls collection for every nested control that it encounters within control tags. Additionally, it adds Literal controls for text between nested control tags. You can override this default behavior by associating a custom control builder class with your control. This is done by applying a control builder attribute to your control, as shown in the following example.

VB

The element in square brackets above is a common language runtime attribute that associates the CustomParse2ControlBuilder class with the CustomParse2 control. You can define your own custom control builder by deriving from ControlBuilder and overriding its methods.

The following sample defines a custom control builder that overrides the GetChildControlType method inherited from ControlBuilder. This method returns the type of the control to be added and can be used to decide which controls will be added. In the example, the control builder will add a child control only if the tag name is "customitem". The code for the control is very similar to the previous example, except for the addition of the custom attribute.

 
VB CustomParse2.aspx

[Run Sample] | [View Source]


Copyright 2001 Microsoft Corporation. All rights reserved.

GoToMyPC | ASP.NET Knowledge Base