Let’s get a feel for web user controls by stepping through a simple example. Let’s say that in your web site, you have many forms consisting of pairs of Label and TextBox controls, like the one shown in Figure 4.10.
All the labels must have a fixed width of 100 pixels, and the text boxes must accept a maximum of 20 characters.
Rather than adding many labels and text boxes to the form, and then having to set all their properties, let’s make life easier by building a web user control that includes a Labelof the specified width, and a TextBoxthat accepts 20 characters; you’ll then be able to reuse the web user control wherever it’s needed in your project.
Create a new file in you working project using the Web User Control template, as shown in Figure ii
Figure i. A simple form
Figure ii. Creating a new Web User Control
Name the file SmartBox.ascx. Then, add the control’s constituent controls—a Label control and a TextBox control—as shown below (for both VB and C# versions):
Visual Basic LearningASP\VB\SmartBox.ascx(excerpt)
<%@ Control Language="VB" ClassName="SmartBox" %>
<script runat="server">
⋮
</script>
<p>
<asp:Label ID="myLabel" runat="server" Text="" Width="100" />
<asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"
MaxLength="20" />
</p>
In Topic 3 we discussed properties briefly, but we didn’t explain how you could create your own properties within your own classes. So far, you’ve worked with many properties of the built-in controls. For example, you’ve seen a lot of code that sets the Text property of the Label control.
As a web user control is a class, it can also have methods, properties, and so on. Our SmartBox control extends the base System.Web.UI.UserControl class by adding two properties:
- LabelTextis a write-only property that allows the forms using the control to set the control’s label text.
- Textis a read-only property that returns the text the user typed into the text box.
Let’s add a server-side scriptelement that will give our control two properties—one called Text, for the text in the TextBox, and one called LabelText, for the text in the Label:
Visual Basic LearningASP\VB\SmartBox.ascx(excerpt)
<%@ Control Language="VB" ClassName="SmartBox" %>
<script runat="server">
Public WriteOnly Property LabelText() As String
Set(ByVal value As String)
myLabel.Text = value
End Set
End Property
Public ReadOnly Property Text() As String
Get
Text = myTextBox.Text
End Get
End Property
</script>
<p>
<asp:Label ID="myLabel" runat="server" Text="" Width="100" />
<asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"
MaxLength="20" />
</p>
C# LearningASP\CS\SmartBox.ascx(excerpt)
<%@ Control Language="C#" ClassName="SmartBox" %>
<script runat="server">
public string LabelText
{
set
{
myLabel.Text = value;
}
}
public string Text
{
get
{
return myTextBox.Text;
}
}
</script>
<p>
<asp:Label ID="myLabel" runat="server" Text="" Width="100" />
<asp:TextBox ID="myTextBox" runat="server" Text="" Width="200"
MaxLength="20" />
</p>
Just like web forms, web user controls can work with code-behind files, but, in an effort to keep our examples simple, we aren’t using them here. We’ll meet more complex web user controls in the chapters that follow.
When you use the SmartBox control in a form, you can set its label and have the text entered by the user, like this:
Visual Basic
mySmartBox.LabelText = "Address:"
userAddress = mySmartBox.Text
C#
mySmartBox.LabelText = "Address:";
userAddress = mySmartBox.Text;
Let’s see how we implemented this functionality. In .NET, properties can be read-only, write-only, or read-write. In many cases, you’ll want to have properties that can be both readable and writeable, but in this case, we want to be able to set the text of the inner Label, and to read the text from the TextBox.
To define a write-only property in VB, you need to use the WriteOnly modifier. Write-only properties need only define a special block of code that starts with the keyword Set. This block of code, called an accessor, is just like a subroutine that takes as a parameter the value that needs to be set. The block of code uses this value to perform the desired action—in the case of the LabelText property, the action sets the Text property of our Label control, as shown below:
Visual Basic LearningASP\VB\SmartBox.ascx(excerpt)
Public WriteOnly Property LabelText() As String
Set(ByVal value As String)
myLabel.Text = value
End Set
End Property
Assuming that a form uses a SmartBox object called mySmartBox, we could set the Text property of the Label like this:
Visual Basic
mySmartBox.LabelText = "Address:"
When this code is executed, the Set accessor of the LabelTextproperty is executed with its value parameter set to Address:. The Set accessor uses this value to set the Text property of the Label.
The other accessor you can use when defining properties is Get, which allows us to read values instead of writing them. Obviously, you aren’t allowed to add a Get accessor to a WriteOnly property, but one is required for a ReadOnly property, such as Text:
Visual Basic LearningASP\VB\SmartBox.ascx(excerpt)
Public ReadOnly Property Text() As String
Get
Text = myTextBox.Text
End Get
End Property
The Textproperty is ReadOnly, but it doesn’t need to be. If you wanted to allow the forms using the control to set some default text to the TextBox, you’d need to add a Set accessor, and remove the ReadOnly modifier.
When you’re defining a property in C#, you don’t need to set any special modifiers, such as ReadOnly or WriteOnly, for read-only or write-only properties. A property that has only a get accessor will, by default, be considered read-only:
C# LearningASP\CS\SmartBox.ascx(excerpt)
public string Text
{
get
{
return myTextBox.Text;
}
}
Likewise, a property that has only a set accessor will be considered to be write-only:
C# LearningASP\CS\SmartBox.ascx(excerpt)
public string LabelText
{
set
{
myLabel.Text = value;
}
}
Using the Web User Control
Once the user control has been created, it can be referenced from any ASP.NET page using the Register directive, as follows:
<%@ Register TagPrefix="prefix" TagName="name" Src="source.ascx" %>
The Register directive requires three attributes:
TagPrefix
the prefix for the user control, which allows you to group related controls together, and avoid naming conflicts
TagName
the control’s tag name, which will be used when the control is added to the ASP.NET page
Src
the path to the .ascx file that describes the user control
After we register the control, we create instances of it using the <TagPrefix:TagName> format. Let’s try an example that uses the SmartBox control. Create a Web Form named ControlTest.aspx in your project folder, and give it this content:
Visual Basic LearningASP\VB\ControlTest.aspx
<%@ Page Language="VB" %>
<%@ Register TagPrefix="sp" TagName="SmartBox"
Src="SmartBox.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.blosums.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Creating ASP.NET Web Server Controls</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<sp:SmartBox ID="nameSb" runat="server"
LabelText="Name:" />
<sp:SmartBox ID="addressSb" runat="server"
LabelText="Address:" />
<sp:SmartBox ID="countrySb" runat="server"
LabelText="Country:" />
<sp:SmartBox ID="phoneSb" runat="server"
LabelText="Phone:" />
</div>
</form>
</body>
</html>
Creating this page by hand will really help you to understand the process of building a web form. In time, you’ll learn how to use Visual Web Developer to do part of the work for you. For example, you can drag a user control from Solution Explorer and drop it onto a web form; Visual Web Developer will register the control and add an instance of the control for you. Loading this page will produce the output we saw in Figure i .
Now, this is a very simple example indeed, but we can easily extend it for other purposes. You can see in the above code snippet that we set the LabelTextproperty directly using the control’s attributes; however, we could have accessed the properties from our code instead. Here’s an example of in which we set the LabelText properties of each of the controls using VB and C#:
Visual Basic
<script runat="server">
Protected Sub Page_Load()
nameSb.LabelText = "Name:"
addressSb.LabelText = "Address:"
countrySb.LabelText = "Country:"
phoneSb.LabelText = "Phone:"
End Sub
</script>
C#
<script runat="server">
protected void Page_Load()
{
nameSb.LabelText = "Name:";
addressSb.LabelText = "Address:";
countrySb.LabelText = "Country:";
phoneSb.LabelText = "Phone:";
}
</script>