Creating User controls and Custom controls in ASP.NET

In this article author explains how to create a simple user control from existing ASP.NET pages, as well as how to create custom controls from scratch.

User control or the .ascx file in ASP.NET is a replacement for the include file feature in ASP. These controls can create using ASP.NET code, just like your ASP.NET Web pages. The difference is that after you have created a user control you can reuse it in multiple ASP.net with a minimum of difficulty.

For example, let’s say that you have created a page that displays some information from a database, perhaps information about an order. Instead of creating a fixed pages does this, it is possible to place the relevant code into a user control, and then insert that into as many different web pages as you want.

In addition it is possible to define properties and methods for user controls. For example you can specify a property for the background color for displaying your database table in a web page, or a method to re-run a database query to check for changes.

Let’s create a simple user control.

A Simple User Control

In Visual Studio .NET, create a new Web application called MyUserWeb. After the standard files have been generated, select the Project-> add new Item menu option, and add a Web User Control called MyUserWeb1.

The files added to our project, with the extensions .ascx and .ascx.cs, work in a similar way to .aspx file. The .aspx file contains our ASP.NET code and looks very similar to a normal .aspx file. The ascx.cs file is our code-behind file, which defines the user control, much in the same way that forms are defined in aspx.cs files.

.ascx file can be viewed in design or HTML view just like .aspx files. Looking at the file in HTML view reveals an important difference. There is no HTML code present, and in particular no <form> element. This is because user controls are inserted inside ASP.NET forms in other files and so don’t need a <form> tag of their own. The generated code is as follows.

.........................................................................

<%
@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUserWeb1.ascx.cs" Inherits="MyUserWeb1" %>

This is very similar to the <%@ page %> directive generated in .aspx files, expect the control is specified rather than page.

Lets add some code to our new control. In the HTML view MyUserWeb1.ascx add the following code.

.........................................................................

<%
@ Control Language="C#" AutoEventWireup="true" CodeFile="MyUserWeb1.ascx.cs" Inherits="MyUserWeb1" %>

<table cellpadding =4>
<tr valign="middle">
<td><asp:Image runat="server" ID="suitPic" ImageUrl="club.bmp" />
</td>
 <td>
 <asp:Label runat="Server" ID="SuitLabel">Club</asp:Label>      
</td>
</
tr>  
</table>

This defines a default site for your control, which is a picture of a club along with a label. Before we add any additional functionality we’ll test this default by adding this control to our project Web page webform1.aspx.

In order to use a custom control in an .aspx file, we first need to specify how we will refer to it, that is, the name of the tag that will represent the control in our HTML. To do this we use the <% @ Register %> directive at the top of the code as follows.

.........................................................................
<%@ Register TagPrefix=”My1” Tagname=”UserWeb1” Scr=”MyUserWeb1.ascx” %>

The TagPrefix and TagName attributes specify the tag name to use in the form <TagPrefix:TagName>, and we use the Src attribute to point to the file containing our user control. Now we can use our control by adding the following elements.

<form id="form1" method="post" runat="server">
    <div>
    <My1:UserWeb1 RunR="SERVER" id="myUserControl" />
    </div> </form>
.........................................................................

User controls aren’t declared by default in the code behind our form, so we also need to add the following declaration to Webform1.aspx.

.........................................................................
public class webForm1 : System.Web.UI.Page
    {
        protected UserWeb1 myUserControl;

This is all we need to do to test our user control. You can see the results after running the code.

As it stands this control groups two existing controls, an image and a label, in a table layout. 

To gain control over the display suit, we can use an attribute on the <My1:UserWeb1> element. Attribute on user control elements are automatically mapped to properties on user controls, so all we have to do to make this work is add a property to the code behind our control, MyUserWeb1.ascx.cs. We’ll call this property Suit, and let it take any Suit value. Add a namespace in the MyUserWeb1.ascx.cs file.

.........................................................................
Namespace MyUserWeb1
{

public enum suit
{
club, diamond, heart, spade
}

}

The MyUserWeb1 class need a member variable to hold the suit type, currentSuit.

Public class MyUserWeb1 : System.Web.UI.UserControl
{

propected System.Web.UI.WebControls.Image suitPic;
propected System.Web.UI.WebControls.Label suitLabel;
protected suit cuttentSuit;

And a property to access this member variable, Suit.

Public suit Suit
{

get{
return currentSuit;
}
set
{
currentSuit = value;
suitPic.ImageUrl = currentSuit.ToString() + “.bmp”;
suitLabel.Text = currentSuit.ToString();
}
}

The set accessory here sets the URL of the image to one of the files we copied earlier, and the text displayed to the suit name.

Next we must add code to WebForm1.aspx so we can access this new property. We could simply specify the suit using the property we have just added.

<My1:UserWeb1 Runat=”server” id=”myUserControl” Suit=”diamond” />


The ASP.NET processor is intelligent enough to get correct enumeration item from the string provided. To make a bit more interesting and interactive, we’ll use a radio button list to select a suit.

.........................................................................

  <form id="form1" method="post" runat="server">
    <div>
    <My1:UserWeb1 RunR="SERVER" id="myUserControl" />
    <asp:RadioButtonList runat="server" ID="suitlist" AutoPostBack="true">
    <asp:ListItem Value="club" Selected="true">Club</asp:ListItem>   
    <asp:ListItem Value="spade"> Spade</asp:ListItem>  
    <asp:ListItem Value="diamond"> Diamond</asp:ListItem>  
    <asp:ListItem Value="Heart"> Heart</asp:ListItem>  
    </asp:RadioButtonList>    
    </div>
    </form>

We also need to add an event handler for the SelectedIndexChanged event of the list, which we can do simply by double-clicking the radio button list control in Design view.

The SuitList_SelectedIndexChanged() method requires the following code in WebForm1.aspx.cs.

protected void suit_SelectedIndexChanged(object sender, System.EventArgs e)
{
myUserControl.suit = (suit_SelectedIndexChanged)Enum.Parse(typeof(suit), suitList.SelectedItem.Value);
}

We know that the value attribute of the <ListItem> elements represent valid values for the suit enumeration we defined earlier, so we simply parse these as enumeration types and use them as values of the suit property of our user control. 

Now we can change the suit when we run our web application.

Next we will give our control some methods. Again, this is very simple. We just add methods to our MyUserWeb1 class.

.........................................................................
public void Club()
    {
        Suit = suit.club;
    }
    public void Spade()
    {
        Suit = suit.spade;
    }
    public void Diamond()
    {
        Suit = suit.diamond;
    }
    public void Heart()
    {
        Suit = suit.heart;
    }

These four methods Club(),Spade(), Diamond() and Heart() change the suit displayed on the screen to the respective suit clicked.

We’ll call these functions from four ImageButton control in our .aspx page.

.........................................................................
<asp:ImageButton runat="server" ID="ClubButton" ImageUrl="club.bmp" OnClick="clubButton_Click" />

    <asp:ImageButton runat="server" ID="spadeButton" ImageUrl="spade.bmp" OnClick="spadeButton_Click" />

    <asp:ImageButton runat="server" ID="diamondButton" ImageUrl="diamond.bmp" OnClick="diamondButton_Click" />

    <asp:ImageButton runat="server" ID="heartButton" ImageUrl="heart.bmp" OnClick="heartButton_Click" />

    </div>
    </form>

We’ll use the following event handlers.

.........................................................................
  protected viod clubButton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            myUserControl.club();
            suitList.SelectedIndex = 0;
        }
        protected viod spadeButton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            myUserControl.spade();
            suitList.SelectedIndex = 1;
        }
        protected viod diamondButton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            myUserControl.diamond();
            suitList.SelectedIndex = 2;
        }
        protected viod heartButton_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            myUserControl.heart();
            suitList.SelectedIndex = 3;
        }

Now we have four new buttons we can use to change the suit in the browser.

Now we have created our user control we can use it in any other Web page simply by using the <%@ Register %> directive and the two source code files (MyUserWeb1.ascx and MyUserWeb1.ascx.cs).


Custom Controls

Custom controls go a step beyond user controls in that they are entirely self-contained in C# assemblies, requiring no separate ASP.NET code. To get the most customizable behavior for our custom control we can derive a class from System.Web.UI.WebControls.WebControl. If we do this then we are creating a full custom control. 


Whatever we create cab used in ASP.NET pages in pretty much the same way. All we need to do is to place the generated assembly in a location where the web application that will use it can find it, and register the element names to use with the <%@ Register %> directive. We will put to assembly in the bin directory of the web application.

The <%@ Register %> directive takes a slightly different syntax for custom controls.

.........................................................................
<%@ Register TagPrefix=”My1” Tagname=”UserWeb1” Assembly=MyCustomWebControls%>

We use the TagPrefix option in the same way as before, but we don’t use the TagName or Src attributes. This is because the custom control assembly we use may several custom controls, and its class will name each of these, so TagName is redundant. 

In the above code we have instruct the program to use an assembly called MyUserWeb1.dll with controls in the MyUserWebs namespace, and use the tag prefix My1. If we have a control called Control1 in the namespace we could use it with the ASP.NET code.

<My1:Control1 Runat=”server” ID=”Mycontrol1” />

Configuring Control Project Configuration

For simplicity we will use a single assembly to hold the custom control. We will create in Visual Studio .NET by choosing a new project of type Web Control Library. We’ll call our library MyCustomWebControl.

Now we have created the project c:\ MyUserControl\CustomControls. There is no need for the project to be created on the Web Server, as with Web Application, since it doesn’t need to be externally accessible in the same way. We can create Web control libraries anywhere, as long as we remember to copy the generated assembly somewhere the web application. 

One technique we can use to facilitate testing is to add a web application project to the same solution. We will call this application MyUserWebsTestApp. For now this is the only application that will use our custom control library, so we can make the output assembly for our library is created in the correct bin directory. We can do this through the property pages for the MyUserWebControls project.

Note that we have changed the Configuration dropdown to all configurations, debug and release build outputs will be placed in the same place. The output path has been changed to C:\Inetpub\wwwroot\ MyUserWebControlsTestApp\bin. To make sure that this is all working by testing the control that is supplied by default in the .cs file. Of our custom control library, WebCustomControl1.cs. We just need to change the following changes to the code in the WebForm1.aspx file, which simply references the newly created control library and embeds the default control in this library into the page body.

.........................................................................

<%@page Language="C#" Codebehind="~/WebForm1.aspx.cs" AutoEventWireup="false" Inherits="MyCustomControlsTestAoo.WebForm1" %>

<%@ Register TagPrefix="My1" Namespace="MyCustomControls" Assembly="MyCustomWebControls" %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<
head>
    <title>My Web Page</title>
    <meta name="GENERATOR" content="Microsoft Visual Studio 7.0" />
    <meta name="CODE_LANGUAGE" content="C#" />
    <meta name="vs_defaultClientScript" content="JavaScript" />      
</head>
<
body MS_POSITIONING="GridLayout"> 
    <form id="form1" method="post" runat="server">
    <My1:UserCustomControl1 id="testControls" RunR="SERVER" Text="code Testing" />
    </form>
</body>
</html>

We can also do this in different way after the control library project has been compiled. Visual Studio .NET Toolbox has a tab called My User Controls that you can use to add your own controls. Right click the tab to which you want to add your new control and choose Add/Remove Items menu option. Next, from the .NET Framework Components tab browse to the OCSCustomWebControls.dll assembly, load it, and then choose controls from the.

The good thing about this is that if we add the control from the Toolbox both a project reference to MyUserWebControls and the <% @ Register%> directive are added automatically to the control. The tag prefix for the control library is also assigned automatically. 

Once thing that isn’t added for us is a using statement to our MyUserWebControlsTestApp namespace in WebForm1.aspx.cs. Instead of fully qualified names for our controls we can add the using statement ourselves.

Using MyUserWebControls;

This will enable us to use our custom controls from the code behind the form without full name qualification. As long as we have the MyUserWebControls library configured as our startup application we can click the Debug button to see our results. Try changing the Test property of the newly added control to Testing again and run the application.

Basic Custom Control

The sample control generated by default is simply a version if the standard <asp:Label> control. The code generated in the .cs file for the project, WebCustomControl.cs, is as follows.

.........................................................................
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace MyUserWebControls
{
    [DefaultProperty ("Text"), 
    ToolboxData ("<{0}:WebCustomControl1 runat=server></{0}
:WebCustomControl1>"
)]
    public class WebCustomControl1 : System.Web.UI.WebControls.WebControl 
    {
    private string test;
    [Bindable (true), Category("Appearance), DefaultValue("")]
        public string Test
            get
            {
                return Text;
            }
    set
    {
    test= Value;
     }
     }
   protected override void Render(HtmlTextWriter output)
{
 output.Write(Text);
}
    }
    }
}

The single class defined here is the WebCustomControl1 class, which is derived from the Web Control class as discussed earlier. The attributes are provided for these classes are ‘DefaultProperty’ and ‘ToolboxData’. 


The RainbowLable derived control

For this example we will derive a control from a Label control and override its Render() method to output multicolored text. To keep the code simple, we will create a new source files as necessary, so for this control add a new .cs code file called RainbowLable.cs to the MyUserWebControls project and add the Following code.

The class derives from the existing Label control (System.Web.UI.Webcontrols.Label) and doesn’t require any additional properties, because the inherited Test one will do file. We have added a new private field, colors(), which contain an array of colors that we’ll cycle through when we output test.

The main functionality of the control is Render(), which we have overridden, because we want to change the HTML output.

To execute this control we need to add it to the form in MyUserWebControlsTestApp.

......................................................................................................................................................
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing; 

namespace
MyUserWebControls
{
    public class RainbowK1 : System.Web.UI.WebControls.Label
    {
        private Color[] colors = new Color[] {
            Color.YellowGreen, Color.Violet, Color.Yellow,Color.Black, Color.DarkGray, Color.DeepPink);

       
protected override void  Render(HtmlTextWriter output)
{
            string text = Text;
            for (int a=0; a < text.Length; a++)
            {

                int rgb = colors[a % colors.Length].ToArgb() & )0xFFFFF;
                output.Write ("<font color='#" + rgb.ToString("X6") + "'>" + text[a] + "</font>");  
            }
        }
    }
        } 

Execute the code and view the results in the browser.

Conclusion

In this article we have learned how to create a simple user control from existing ASP.NET pages, as well as how to create custom controls from scratch. You can also create the user controls and custom controls according to your requirements.

Language :  C# & ASP.NET
Platform: Windows
Level: Intermediate




Added on October 1, 2007 Comment

Comments

Post a comment

Your name:

Comment: