User Controls

by John Peterson


Introduction

Server controls are one of the things that make developing with ASP.NET so
simple and powerful at the same time. We’ve discussed HTML and web server
controls and have showed you how to use them in your ASP.NET pages, but what
if there’s not a control that does exactly what you want to do?

Like most everything in ASP.NET there’s really no magic involved with server controls.
In fact, you can build your own controls and use them on your pages just like you
use the ones that ship with .NET. Controls that you build are called user controls and
they are the topic of this lesson.

Writing Your First User Control

I know how to use a server control, but writing one’s got to be hard.

Actually, writing a basic user control (also sometimes called pagelets)
couldn’t be much easier… most any ASP.NET page can be used as a server
control. Here’s a simple example:

basic.ascx

<p>
This is a user control... really!
</p>

That’s it. Looking at that, I know you’re probably thinking that I’m either drunk or
half-asleep, but I’m really not (or am I?)… the above can easily be used as a user
control. Granted it doesn’t do that much, but it’s great for illustrating that
these things are really only as complicated as you make them. Notice the .ascx extension…
it’s the customary extension given to pages meant to be used as a control. It’s
not really anything special, but it does keep things easier to understand and by default
.ascx files are prevented from being directly executed and served by IIS.

Now that we’ve created our user control, here’s a sample of how to use it in an
ASP.NET web page.

basic.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="asp101samps" TagName="SomeText"
	Src="basic.ascx" %>

<html>
<head>
<title>ASP.NET User Control Sample - Basic</title>
</head>
<body bgcolor="#FFFFFF">

<asp101samps:SomeText runat="server" />

</body>
</html>

The above page will output a standard HTML page with the text contained in our user
control in place of the user control’s tag. How does it do it?
The magic here is in the Register directive.
To use it you’ll need to specify three attributes:

TagPrefix
The TagPrefix attribute defines a namespace in which the control will live.
You can think of this as the world in which the control will live. Because of
this, you can have different controls with the same name and as long as they
have a different TagPrefix (and as a result different namespaces) they can
peacefully co-exist on the same page.
TagName
The TagName attribute determines the name by which the control will be refered to. It needs to be
unique within the namespace, but you can choose whatever you like. Generally
names are choosen that are indicative of what the control actually does.
Src
The Src (or source) attribute simply specifies where the code that makes up
the control being defined is to be found. Vitual paths are used so the value
should be something like "control.ascx" or "/path/control.ascx"
and not a physical path like "C:pathcontrol.ascx."

Once you’ve added the Register directive, the control is registered and can be used
just like any other server control. You specify the TagPrefix and TagName in the
control’s tag just like you would with a built in control and make sure you’ve got the
runat="server" attribute and you’re ready to roll. Here’s the
basic form for a user control’s tag:

<TagPrefix:TagName runat="server" />

Giving Your Control Properties

That’s great, but I could’ve just typed that text into the web page and it would’ve
been faster and easier.

If that’s all controls could do they would’ve been called include files! Thank
goodness it doesn’t stop there. I’m going to continue to use our stupidly simple
example to keep things simple, but we are going to take it up a notch. This time
around I’ve added two properties to the control – one to control the color and one
to control the text.

properties.ascx

<script language="VB" runat="server">
	Public Color As String = "black"
	Public Text As String = "This is a user control... really!"
</script>

<p>
<font color="<%= Color %>">
<%= Text %>
</font>
</p>

By default the control will look the same as before, but now we can modify
the color or text it emits either by setting properties in the control’s tag
or programmatically from our code (as long as we give the control an id
attribute by which to reference it). Also note that I’m able to reuse the
same control a number of times in the page and set the properties of each
instance indepedently.

properties.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="asp101samps" TagName="SomeText"
	Src="properties.ascx" %>

<script language="VB" runat="server">
	Sub Page_Load(Sender As Object, E As EventArgs)
		UserCtrl1.Color = "green"
		UserCtrl1.Text = "This control's properties were " _
			& "set programmatically!"
    End Sub
</script>

<html>
<head>
<title>ASP.NET User Control Sample - Properties</title>
</head>
<body bgcolor="#FFFFFF">

<asp101samps:SomeText runat="server" />

<asp101samps:SomeText Color="red" runat="server" />

<asp101samps:SomeText Text="This is quite cool!" runat="server" />

<asp101samps:SomeText Color="blue" Text="Ain't It?" runat="server" />

<asp101samps:SomeText id="UserCtrl1" runat="server" />

</body>
</html>

Having Your Control Handle Events

That’s better, but how much more can we get them to do for us?

You can get your control to do almost anything you want it to. In the next set
of code listings the control will handle the Page_Load event all by itself.
This type of event handling allows you to write controls that need very little
if any maintaining-code to be written in the page hosting the control. The
controls can handle all their own events.

In addition, this control encapsulates a asp textbox control. I’ve even hooked
our control’s name property up to the text property of the textbox.

events.ascx

<script language="VB" runat="server">
	Sub Page_Load(Src As Object, E As EventArgs)
		Dim strInitialText As String = "Please Enter a Name!"

		If Page.IsPostBack Then
			If txtName.Text = strInitialText
				txtName.Text = ""
			End If
		Else
			txtName.Text = strInitialText
		End If
	End Sub

	Public Property Name As String
		Get
			Return txtName.Text
		End Get
		Set
			txtName.Text = Value
		End Set
	End Property
</script>

Name: <asp:textbox id="txtName" runat="server" />

<asp:RequiredFieldValidator ControlToValidate="txtName"
	id="valtxtName" Display="Dynamic" runat=server>
	Please Enter a Name!
</asp:RequiredFieldValidator>
events.aspx

<%@ Page Language="VB" ClientTarget="downlevel" %>
<%@ Register TagPrefix="asp101samps" TagName="SomeText"
	Src="properties.ascx" %>
<%@ Register TagPrefix="asp101samps" TagName="TextBox"
	Src="events.ascx" %>

<script language="VB" runat="server">
	Sub Page_Load(Sender As Object, E As EventArgs)
		txtLabel.Text = ""

		' The textbox control handles it's own stuff
		' in it's own Page_Load event handler.
	End Sub

	Sub btnSubmit_Click(Sender As Object, E As EventArgs)
		' Sets the label to the textbox's text
		txtLabel.Text = txtName.Name

		' I don't need to worry about validation since
		' my user control does it for me.
	End Sub
</script>

<html>
<head>
<title>ASP.NET User Control Sample - Validation & Events</title>
</head>
<body bgcolor="#FFFFFF">

<form runat="server">

	<asp101samps:TextBox id="txtName" runat="server" />

	<br />

	<asp:button id="btnSubmit" onClick="btnSubmit_Click"
		text="Submit" runat="server" />

</form>

<asp101samps:SomeText id="txtLabel" runat="server" />

</body>
</html>

In the example above I used the property syntax for defining and modifying the
properties of our user control. I could have used this syntax for the earlier
samples as well but I wasn’t doing anything that required it. The property style
of doing this
allows you to execute commands upon setting or retreiving of the property,
but it’s a little more confusing and doesn’t really gain you anything with simple
properties which don’t require any execution when modified.

That’s About It

That should give you enough info to get started creating your own user controls.
They can be as simple or as complex as you want, but they really do make reusability
much easier then it ever was in classic ASP.

You can download the code from this article below.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read