Overview of user controls vs. custom controls (893667)



The information in this article applies to:

  • Microsoft ASP.NET (included with the .NET Framework 1.1)
  • Microsoft ASP.NET (included with the .NET Framework 1.0)

ASP.NET Support Voice column

Overview of user controls vs. custom controls

To customize this column to your needs, we want to invite you to submit your ideas about topics that interest you and issues that you want to see addressed in future Knowledge Base articles and Support Voice columns. You can submit your ideas and feedback using the Ask For It form. There's also a link to the form at the bottom of this column.

Introduction

Hi! This is Parag, and I am a support engineer working with the Microsoft ASP.NET support group for more than a year now. Prior to joining Microsoft, I worked on Web-based projects and desktop applications using Microsoft technologies. While providing quality support to customers, I have seen cases where there was some confusion around custom controls, and I would just like to take some time to explain some concepts around custom controls. As bad as it looks, believe me, once you get the hang of it, you will be in a better position to appreciate ASP.NET.

Overview

In this month's column, I'll discuss the following topics:
  • What are user controls?
  • What are custom controls?
  • What are the basic differences between user controls and custom controls?
I'll also introduce a few of the advanced topics that concern custom controls, such as state management and the rendering of custom controls.

What are user controls?

User controls are custom, reusable controls, and they use the same techniques that are employed by HTML and Web server controls. They offer an easy way to partition and reuse common user interfaces across ASP.NET Web applications. They use the same Web Forms programming model on which a Web Forms page works. For more details about the Web Forms programming model, visit the following Microsoft Developer Network (MSDN) Web sites:

How to create a user control

The syntax you use to create a user control is similar to the syntax you use to create a Web Forms page (.aspx). The only difference is that a user control does not include the <html>, <body>, and <form> elements since a Web Forms page hosts the user control. To create a user control, follow these steps:
  1. Open a text or HTML editor, and create a server-side code block exposing all the properties, methods, and events.
    <script language="C#" runat="server">
       public void button1_Click(object sender, EventArgs e)
       {
          label1.Text = "Hello World!!!";
       }
    </script>
    
  2. Create a user interface for the user control.
    <asp:Label id="label1" runat="server"/>
     <br><br>
    <asp:button id="button1" text="Hit" OnClick="button1_Click" runat="server" />
    

How to use a user control in a Web Forms page

  1. Create a new Web Forms page (.aspx) in Microsoft Visual Studio .NET 2002, Microsoft Visual Studio .NET 2003, Microsoft Visual Studio 2005, or any text editor.
  2. Declare the @ Register directive. For example, use the following code.
    <%@ Register TagPrefix="UC" TagName="TestControl" Src="test.ascx" %>
    Note Assume that the user control and the Web Forms page are in the same location.
  3. To use the user control in the Web Forms page, use the following code after the @ Register directive.
    <html>
        <body>
              <form runat="server">
                   <UC:TestControl id="Test1" runat="server"/>
              </form>
        </body>  
    </html>
    

How to create an instance of a user control programmatically in the code behind file of a Web Forms page

The previous example instantiated a user control declaratively in a Web Forms page using the @ Register directive. However, you can instantiate a user control dynamically and add it to the page. Here are the steps for doing that:
  1. Create a new Web Forms page in Visual Studio.
  2. Navigate to the code behind file generated for this Web Forms page.
  3. In the Page_Load event of the Page class, write the following code.
    // Load the control by calling LoadControl on the page class.
    Control c1 = LoadControl("test.ascx");
                
    // Add the loaded control in the page controls collection.	
    Page.Controls.Add(c1);
    
    Note You can add a user control dynamically at certain events of the page life cycle.

    For more information, visit the following Web sites:

How a user control is processed

When a page with a user control is requested, the following occurs:
  • The page parser parses the .ascx file specified in the Src attribute in the @ Register directive and generates a class that derives from the System.Web.UI.UserControl class.
  • The parser then dynamically compiles the class into an assembly.
  • If you are using Visual Studio, then at design time only, Visual Studio creates a code behind file for the user control, and the file is precompiled by the designer itself.
  • Finally, the class for the user control, which is generated through the process of dynamic code generation and compilation, includes the code for the code behind file (.ascx.cs) as well as the code written inside the .ascx file.

What are custom controls?

Custom controls are compiled code components that execute on the server, expose the object model, and render markup text, such as HTML or XML, as a normal Web Form or user control does.

How to choose the base class for your custom control

To write a custom control, you should directly or indirectly derive the new class from the System.Web.UI.Control class or from the System.Web.UI.WebControls.WebControl class:
  • You should derive from System.Web.UI.Control if you want the control to render nonvisual elements. For example, <meta> and <head> are examples of nonvisual rendering.
  • You should derive from System.Web.UI.WebControls.WebControl if you want the control to render HTML that generates a visual interface on the client computer.
If you want to change the functionality of existing controls, such as a button or label, you can directly derive the new class with these existing classes and can change their default behavior.

In brief, the Control class provides the basic functionality by which you can place it in the control tree for a Page class. The WebControl class adds the functionality to the base Control class for displaying visual content on the client computer. For example, you can use the WebControl class to control the look and styles through properties like font, color, and height.

How to create and use a simple custom control that extends from System.Web.UI.Control using Visual Studio

  1. Start Visual Studio.
  2. Create a class library project, and give it a name, for example, CustomServerControlsLib.
  3. Add a source file to the project, for example, SimpleServerControl.cs.
  4. Include the reference of the System.Web namespace in the references section.
  5. Check whether the following namespaces are included in the SimpleServerControl.cs file.
    System
    System.Collections
    System.ComponentModel
    System.Data
    System.Web
    System.Web.SessionState
    System.Web.UI
    System.Web.UI.WebControls
    
  6. Inherit the SimpleServerControls class with the Control base class.
    public class SimpleServerControl : Control
  7. Override the Render method to write the output to the output stream.
    protected override void Render(HtmlTextWriter writer) 
    {
    	 writer.Write("Hello World from custom control");
    }
    
    Note The HtmlTextWriter class has the functionality of writing HTML to a text stream. The Write method of the HtmlTextWriter class outputs the specified text to the HTTP response stream and is the same as the Response.Write method.
  8. Compile the class library project. It will generate the DLL output.
  9. Open an existing or create a new ASP.NET Web application project.
  10. Add a Web Forms page where the custom control can be used.
  11. Add a reference to the class library in the references section of the ASP.NET project.
  12. Register the custom control on the Web Forms page.
    <%@ Register TagPrefix="CC " Namespace=" CustomServerControlsLib " Assembly="CustomServerControlsLib " %>
  13. To instantiate or use the custom control on the Web Forms page, add the following line of code in the <form> tags.
    <form id="Form1" method="post" runat="server">
        <CC:SimpleServerControl id="ctlSimpleControl" runat="server">
        </CC:SimpleServerControl >
    </form>
    
    Note In this code, SimpleServerControl is the control class name inside the class library.
  14. Run the Web Forms page, and you will see the output from the custom control.
If you are not using Visual Studio, you need to perform the following steps:
  1. Open any text editor.
  2. Create a file named SimpleServerControl.cs, and write the code as given in steps 1 through 14.
  3. In the PATH variable, add the following path:

    c:\windows (winnt)\Microsoft.Net\Framework\v1.1.4322

  4. Start a command prompt, and go to the location where SimpleServerControl.cs is present.
  5. Run the following command:

    csc /t:library /out: CustomServerControlsLib. SimpleServerControl.dll /r:System.dll /r:System.Web.dll SimpleServerControl.cs

    For more information about the C# compiler (csc.exe), visit the following MSDN Web site:
  6. To run the custom control on the Web Forms page, do the following:
    1. Create a directory under the wwwroot folder.
    2. Start Microsoft Internet Information Services (IIS) Manager, and mark the new directory as the virtual root directory.
    3. Create a Bin folder under the new directory.
    4. Copy the custom control DLL into the Bin folder.
    5. Place the sample Web Forms page that you created in the previous steps inside the new directory.
    6. Run the sample page from IIS Manager.
Now that you have built a simple custom control, let's look at how to expose properties and apply design-time attributes on that custom control.

How to expose properties on the custom control

I will build on the previous example and introduce one or more properties that can be configured while using the custom control on the Web Forms page.

The following example shows how to define a property that will display a message from the control a certain number of times, as specified in the property of the control:
  1. Open SimpleServerControl.cs in a text editor.
  2. Add a property in the SimpleServerControl class.
    public class SimpleServerControl : Control
    {
       private int noOfTimes;
       public int NoOfTimes
       {
           get { return this.noOfTimes; }
           set { this.noOfTimes = value; }
       } 
       protected override void Render (HtmlTextWriter writer)
       {
         for (int i=0; i< NoOfTimes; i++)
         {
           write.Write("Hello World.."+"<BR>");
         } 
       }
    }
    
  3. Compile the custom control.
  4. To use the custom control on the Web Forms page, add the new property to the control declaration.
    <CC:SimpleServerControl id="ctlSimpleControl" NoOfTimes="5" runat="server"></CC:SimpleServerControl>
  5. Running the page will display the message "Hello world" from the custom control as many times as specified in the property of the control.

How to apply design-time attributes on the custom control

Why design-time attributes are neededThe custom control that you built in the previous example works as expected. However, if you want to use that control in Visual Studio, you may want the NoOfTimes property to be automatically highlighted in the Properties window whenever the custom control is selected at design time.

To make this happen, you need to provide the metadata information to Visual Studio, which you can do by using a feature in Visual Studio called attributes. Attributes can define a class, a method, a property, or a field. When Visual Studio loads the custom control's class, it checks for any attributes defined at the class, method, property, or field level and changes the behavior of the custom control at design time accordingly.

To find more information about attributes, visit the following MSDN Web site: Let's build a sample that uses commonly used attributes:
  1. Open SimpleServerControl.cs in a text editor.
  2. Introduce some basic attributes at the class level, for example, DefaultProperty, ToolboxData, and TagPrefixAttrbute. We'll build our sample on these three attributes.
            [
    	// Specify the default property for the control.		
    	DefaultProperty("DefaultProperty"),
    	
    	// Specify the tag that is written to the aspx page when the
            // control is dragged from the Toolbox to the Design view. 
    	// However this tag is optional since the designer automatically 
    	// generates the default tag if it is not specified.		
    	ToolboxData("<{0}:ControlWithAttributes runat=\"server\">" +
    		"</{0}:ControlWithAttributes>")
    	]
    	public class ControlWithAttributes : Control
    	{
    		private string _defaultProperty;
    		public string DefaultProperty
    		{
    			get { return "This is a default property value"; }
    			set { this._defaultProperty = value; }
    		}
    
    		protected override void Render(HtmlTextWriter writer)
    		{
    			writer.Write("Default Property --> <B>" + 
    			DefaultProperty + "</B>");
    		}
             }
    
  3. There is one more tag called TagPrefixAttrbute. It is an assembly-level attribute that provides a prefix to a tag when you drag the control from the Toolbox to the designer. Otherwise, the designer generates a prefix such as "cc1" by default. TagPrefixAttrbute is not directly applied to the control class. To apply TagPrefixAttrbute, open AssemblyInfo.cs, include the following line of code, and then rebuild the project.
    [assembly:TagPrefix("ServerControlsLib ", "MyControl")]
    Note If you want to build the source using the command line, you need to create the AssemblyInfo.cs file, place the file in the directory that contains all the source files, and run the following command to build the control:

    > csc /t:library /out: ServerControlsLib.dll /r:System.dll /r :System.Web.dll *.cs

What are the basic differences between user controls and custom controls?

Now that you have a basic idea of what user controls and custom controls are and how to create them, let's take a quick look at the differences between the two.
FactorsUser controlCustom control
DeploymentDesigned for single-application scenarios

Deployed in the source form (.ascx) along with the source code of the application

If the same control needs to be used in more than one application, it introduces redundancy and maintenance problems
Designed so that it can be used by more than one application

Deployed either in the application's Bin directory or in the global assembly cache

Distributed easily and without problems associated with redundancy and maintenance
CreationCreation is similar to the way Web Forms pages are created; well-suited for rapid application development (RAD)Writing involves lots of code because there is no designer support
ContentA much better choice when you need static content within a fixed layout, for example, when you make headers and footersMore suited for when an application requires dynamic content to be displayed; can be reused across an application, for example, for a data bound table control with dynamic rows
DesignWriting doesn't require much application designing because they are authored at design time and mostly contain static dataWriting from scratch requires a good understanding of the control's life cycle and the order in which events execute, which is normally taken care of in user controls

Advanced topics

Next, let's take a look at a few of the advanced features that you may use while developing custom controls.

State management

Web applications are built on HTTP, which is stateless. A page and its child controls are created on every request and are disposed of after the request is over. To maintain state in classic ASP programming, you use session and application objects. But for that, you need to do lots of coding. To avoid this, ASP.NET provides a mechanism known as view state for maintaining state across several requests. To learn more about state management and view state, visit the following MSDN Web sites:Example using view state in a custom controlViewStateExample.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;

namespace ServerControlLib
{
	/// <summary>
	/// When a page framework reloads this control after postback, it   
        /// will restore the values which are in view state.
	/// This control can easily perform state management without 
        /// implementing our own logic for maintaining the state.
	/// </summary>
	public class ViewStateExample : WebControl
	{
		// Text to be displayed in Text box control.
		private string _text;
		
		/*
		 * This property needs to be populated before every 
                 * postback in order to 
		 * retain its value.
		*/ 
		public string Text
		{
			get { return (_text == null) ? "_text property is empty"  : _text; }
			set { _text = value; }
		}

		/*
		 * This property needs to be filled once and should be 
                 * available on the successive postbacks.
		*/ 
		public string TextInViewState
		{
			get
			{
				object o = ViewState["TextInViewState"];
				return (o == null) ? "View state is empty" : (string)o;
			}
			set { ViewState["TextInViewState"] = value; } 
		}

		/*
		 * Over-ridden method on WebControl base class which                   
                 * displays both of the property values 
		 * i.e. one stored in view state and other which is not 
                 * saved in view state.
		*/
		protected override void RenderContents(HtmlTextWriter writer)
		{
			writer.Write("Text Without View State = ");
			writer.Write(Text);
			writer.Write("<hr><br>");
			writer.Write("Text In View State = ");
			writer.Write(TextInViewState);
		}
	}
}
Example using the previous control on a Web Forms pageViewStateExampleDemo.aspx
<%@ Page Language="C#" %>
<%@ Register TagPrefix="CC" Namespace="ServerControlLib" Assembly = "ServerControlLib" %>

<html>
  <head>
    <script runat="server">
      void button1_Click(object sender, EventArgs e)
      {
          Control1.Text = textbox1.Text;
          Control1.TextInViewState = textbox2.Text;
      }
    </script>
  </head>
  <body>
    <form runat="server" ID="Form1">
      <br>
      Property Value Without View State: <asp:TextBox id="textbox1" 
        runat="server" />
      <br>
      Property Value with View State: <asp:TextBox id="textbox2" 
        runat="server" />

      <asp:Button text="Cause Postback" onClick="button1_Click" 
        id="button1" Runat="server" />

      Output from the ViewStateExample Control :
      <CC:ViewStateExample id="Control1" runat="server"/>
    </form>
  </body>
</html>

Rendering

In this section, I'll briefly describe what methods you should override when you derive a custom control from either the Control class or the WebControl class.Rendering methods of the System.Web.UI.Control classFor information about the rendering methods of the System.Web.UI.Control class, visit the following MSDN Web sites:How a control is rendered on the pageEvery page has a control tree that represents a collection of all the child controls for that page. To render the control tree, an object of the HtmlTextWriter class is created that contains the HTML to be rendered on the client computer. That object is passed to the RenderControl method. In turn, the RenderControl method invokes the Render method. Then, the Render method calls the RenderChildren method on each child control, making a recursive loop until the end of the collection is reached. This process is best explained by the following example code.
public void RenderControl(HtmlTextWriter writer) 
{
    // Render method on that control will only be called if its visible property is true.
    if (Visible)
    {
        Render(writer);
    }
}

protected virtual void Render(HtmlTextWriter writer) 
{
    RenderChildren(writer);
}
protected virtual void RenderChildren(HtmlTextWriter writer) 
{
    foreach (Control c in Controls) 
    {
        c.RenderControl(writer);
    }
} 
Rendering methods of the System.Web.UI.WebControl classFor information about the rendering methods of the System.Web.UI.WebControl class, visit the following MSDN Web sites:How the rendering of the WebControl class takes placeThe following code example shows the Render method for the custom control.
protected override void Render(HtmlTextWriter writer)
{
    RenderBeginTag(writer);
    RenderContents(writer);
    RenderEndTag(writer);
}
You don't need to override the Render method for the WebControl class. If you want to render contents within the WebControl class, you need to override the RenderContents method. However, if you still want to override the Render method, you must override the RenderBeginTag method as well as the RenderEndTag method in the specific order that is shown in the previous code example.

Conclusion

That's all for now on user controls and custom controls in ASP.NET 1.0 and ASP.NET 1.1. I hope that this column helps you understand the basic differences between them and the various approaches you can take to develop them.

Thank you for your time. We expect to write more about the advanced topics for custom controls, such as state management, control styles, composite controls, and design-time support for custom controls, in the near future.

For more information about controls, visit the following MSDN Web sites:
As always, feel free to submit ideas on topics you want addressed in future columns or in the Knowledge Base using the Ask For It form.

Modification Type:MajorLast Reviewed:11/23/2005
Keywords:kbhowto kbASP KB893667 kbAudITPRO kbAudDeveloper