Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1194Chapter 26: User and Server Controls User Controls User controls represent the simplest form of ASP.NET control encapsulation.. Listing 26-3
Trang 1Chapter 25: File I/O and Streams
Listing 25-29: Sending mail from a Web page
VB
Dim message As _
New System.Net.Mail.MailMessage("webmaster@ineta.org", "webmaster@ineta.org")
message.Subject = "Sending Mail with ASP.NET 3.5"
message.Body = _
"This is a sample email which demonstrates sending email using ASP.NET 3.5"
Dim smtp As New System.Net.Mail.SmtpClient("localhost")
smtp.Send(message)
C#
System.Net.Mail.MailMessage message =
new System.Net.Mail.MailMessage("webmaster@ineta.org","webmaster@ineta.org");
message.Subject = "Sending Mail with ASP.NET 3.5";
message.Body =
"This is a sample email which demonstrates sending email using ASP.NET 3.5";
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("localhost");
smtp.Send(message);
In this sample, you first create aMailMessageobject, which is the class that contains the actual message
you want to send TheMailMessageclass requires the To and From address be provided to its
construc-tor, and you can either provide the parameters as strings, or you can use theMailAddressCollection
class to provide multiple recipients’ e-mail addresses
After you create theMessage, you use theSmtpClientclass to actually send the message to your local
SMTP server TheSmtpClientclass allows you to specify the SMTP Server from which you want to relay
your e-mail
Summar y
In this chapter, you looked at some of the other classes in the NET Framework You looked at
manag-ing the local file system by usmanag-ing classes in theSystem.IOnamespace such asDirectoryInfoand the
FileInfo, and you learned how to enumerate the local file system and manipulate both directory and
file properties and directory and file Access Control Lists Additionally, the chapter discussed the rich
functionality NET provides for working with paths
The chapter also covered how the NET Framework enables you to read and write data to a multitude
of data locations, including the local file system, network file system, and even system memory through
a commonStreamarchitecture The Framework provides you with specialized classes to deal with each
kind of data location Additionally, the Framework makes working with streams even easier by
provid-ingReaderandWriterclasses These classes hide much of the complexity of reading from and writing
to underlying streams Here, too, the Framework provides you with a number of differentReaderand
Writerclasses that give you the power to control exactly how your data is read or written, be it character,
binary, string, or XML
Trang 2Evjen c25.tex V2 - 01/28/2008 3:42pm Page 1191
Chapter 25: File I/O and Streams
You were also introduced to a new feature of the NET 2.0 Framework that allows you to communicate with serial ports
Finally, you learned about the variety of network communication options the NET Framework provides From making and sending Web requests over HTTP, FTP, and File, to sending mail, the NET Framework offers you a full plate of network communication services
1191
Trang 3User and Ser ver Controls
In an object-oriented environment like NET, the encapsulation of code into small, single-purpose,
reusable objects is one of the keys to developing a robust system For instance, if your application
deals with customers, you might want to consider creating a customer’s object that encapsulates
all the functionality a customer might need The advantage is that you create a single point with
which other objects can interact, and you have only a single point of code to create, debug, deploy,
and maintain In this scenario, the customer object is typically known as a business object because it
encapsulates all the business logic needed for a customer
Several other types of reusable objects are available in NET In this chapter, we concentrate on
discussing and demonstrating how you can create reusable visual components for an ASP.NET
application The two types of reusable components in ASP.NET are user controls and server
con-trols
A user control encapsulates existing ASP.NET controls into a single container control, which you can
easily reuse throughout your Web project
A server control encapsulates the visual design, behavior, and logic for an element that the user
interacts with on the Web page
Visual Studio ships with a large number of server controls that you are probably already familiar
with, such as the Label, Button, and TextBox controls This chapter talks about how you can create
custom server controls and extend existing server controls
Because the topics of user controls and server controls are so large, and because discussing the
intricacies of each could easily fill an entire book by itself, this chapter can’t possibly investigate
every option available to you Instead, it attempts to give you a brief overview of building and
Trang 4Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1194
Chapter 26: User and Server Controls
User Controls
User controls represent the simplest form of ASP.NET control encapsulation Because they are the
sim-plest, they are also the easiest to create and use Essentially a user control is the grouping of existing server
controls into a single-container control This enables you to create powerful objects that you can easily
use throughout an entire Web project
Creating User Controls
Creating user controls is very simple in Visual Studio 2008 To create a new user control, you first add a
new User Control file to your Web site From the Website menu, select the Add New Item option After
the Add New File dialog appears, select the Web User Control File template from the list and click OK
Notice that after the file is added to the project, the file has an.ascxextension This extension signals
to ASP.NET that this file is a user control If you attempt to load the user control directly into your
browser, ASP.NET returns an error telling you that this type of file cannot be served to the client
If you look at the HTML source (shown in Listing 26-1) for the user control, you see several interesting
differences from a standard ASP.NET Web page
Listing 26-1: A Web user control file template
<%@ Control Language="VB" ClassName="WebUserControl1" %>
<script runat="server">
</script>
First, notice that the source uses the@Controldirective rather than the@Pagedirective, which a standard
Web page would use Second, notice that unlike a standard ASP.NET Web page, no other HTML tags
besides the<script>tags exist in the control The Web page containing the user control provides the
basic HTML, such as the<body>and<form>tags In fact, if you try to add a server-side form tag to the
user control, ASP.NET returns an error when the page is served to the client The error message tells you
that only one server-side form tag is allowed in your Web page
To add controls to the form, simply drag them from the Toolbox onto your user control Listing 26-2
shows the user control after a Label and a Button have been added
Listing 26-2: Adding controls to the Web user control
<%@ Control Language="VB" ClassName="WebUserControl2" %>
<script runat="server">
</script>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" />
After you add the controls to the user control, you put the user control onto a standard ASP.NET Web
page To do this, drag the file from the Solution Explorer onto your Web page
1194
Trang 5Chapter 26: User and Server Controls
If you are familiar with using user controls in prior versions of Visual Studio, you probably remember the
gray control representation that appeared in the page designer when you dropped a user control onto a
Web page In Visual Studio 2005, this experience was improved and user controls are now fully rendered
on the host Web page during design time This allows you to see an accurate representation of what the
entire page will look like after it is rendered to the client.
Figure 26-1 shows the user control after it has been dropped onto a host Web page
Figure 26-1
After you have placed the user control onto a Web page, open the page in a browser to see the fully
rendered Web page
User controls fully participate in the page-rendering lifecycle, and controls contained within a user
control behave identically to controls placed onto a standard ASP.NET Web page This means that the
user control has its own page execute events (such as Init, Load, and Prerender) that execute as the page
Trang 6Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1196
Chapter 26: User and Server Controls
is processed It also means that child control events, such as a button-click event, will behave identically
Listing 26-3 shows how to use the User ControlsPage_Loadevent to populate the label and to handle the
button-click event
Listing 26-3: Creating control events in a user control
VB
<%@ Control Language="VB" ClassName="WebUserControl1" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Me.Label1.Text = "The quick brown fox jumped over the lazy dog"
End Sub
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Me.Label1.Text = "The quick brown fox clicked the button on the page"
End Sub
</script>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
C#
<%@ Control Language="C#" ClassName="WebUserControl1" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.Label1.Text = "The quick brown fox jumped over the lazy dog";
}
protected void Button1_Click(object sender, EventArgs e)
{
this.Label1.Text = "The quick brown fox clicked the button on the page";
}
</script>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
Now when you render the Web page, you see that the text of the label changes as the user control loads,
and again when you click the bottom of the page In fact, if you put a breakpoint on either of these two
events, you can see that ASP.NET does indeed break, even inside the user control code when the page is
executed
Interacting with User Controls
So far, you have learned how you can create user controls and add them to a Web page You have also
learned how user controls can execute their own code Most user controls, however, are not islands on
their parent page Many scenarios require that the host Web page be able to interact with user controls
that have been placed on it For instance, you may decide that the text you want to load in the label must
be given to the user control by the host page To do this, you simply add a public property to the user
control, and then assign text using the property Listing 26-4 shows the modified user control
1196
Trang 7Chapter 26: User and Server Controls Listing 26-4: Exposing user control properties
VB
<%@ Control Language="VB" ClassName="WebUserControl" %>
<script runat="server">
Private _text As String
Public Property Text() As String
Get
Return _text End Get
Set(ByVal value As String)
_text = value End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Me.Label1.Text = Me.Text
End Sub
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Me.Label1.Text = "The quick brown fox clicked the button on the page"
End Sub
</script>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
C#
<%@ Control Language="C#" ClassName="WebUserControl" %>
<script runat="server">
private string _text;
public string Text
{
get {
return _text;
}
set {
_text = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
this.Label1.Text = this.Text;
}
Trang 8Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1198
Chapter 26: User and Server Controls
protected void Button1_Click(object sender, EventArgs e)
{
this.Label1.Text = "The quick brown fox clicked the button on the page";
}
</script>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
After you modify the user control, you simply populate the property from the host Web page
Listing 26-5 shows how to set theTextproperty in code, but public properties exposed by user controls
will also be exposed by the Property Browser
Listing 26-5: Populating user control properties from the host Web page
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Me.WebUserControl1.Text = "The quick brown fox jumped over the lazy dog"
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
this.WebUserControl1.Text = "The quick brown fox jumped over the lazy dog";
}
User controls are simple ways of creating powerful, reusable components in ASP.NET They are easy
to create using the built-in templates Because they participate fully in the page lifecycle, you can create
controls that can interact with their host page and even other controls on the host page
Loading User Controls Dynamically
User controls can also be created and added to the Web form dynamically at runtime The ASP.NET
Pageobject includes theLoadControlmethod, which allows you to load user controls at runtime by
providing the method with a virtual path to the user control you want to load The method returns a
genericControlobject that you can then add to the page’sControlscollection Listing 26-6 demonstrates
how you can use theLoadControlmethod to dynamically add a user control to a Web page
Listing 26-6: Dynamically adding a user control
VB
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myForm As Control = Page.FindControl("form1") Dim c1 As Control = LoadControl("~/WebUserControl.ascx") myForm.Controls.Add(c1)
End Sub
</script>
1198
Trang 9Chapter 26: User and Server Controls
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
C#
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Control myForm = Page.FindControl("Form1");
Control c1 = LoadControl("~/WebUserControl.ascx");
myForm.Controls.Add(c1);
}
</script>
The first step in adding a user control to the page is to locate the page’s Form control using the
FindControlmethod Should the user control contain ASP.NET controls that render form elements
such as a button or text box, this user control must be added to the Form element’sControls
collection
It is possible to add user controls containing certain ASP.NET elements such as a Label, HyperLink, or
Image directly to thePageobject’sControlscollection; however, it is generally safer to be consistent
and add them to the Form Adding a control that must be contained within the Form, such as a Button
control, to thePages Controlscollection results in a runtime parser error.
After the form has been found, the sample uses the Page’sLoadControl()method to load an instance of the user control The method accepts a virtual path to the user control you want to load and returns the loaded user control as a genericControlobject
Finally, the control is added to theFormobject’sControlscollection You can also add the user
control to other container controls that may be present on the Web page, such as a Panel or
Placeholder control
Remember that you need to re-add your control to the ASP.NET page each time the page performs a
postback.
After you have the user control loaded, you can also work with its object model, just as you can with any other control To access properties and methods that the user control exposes, you cast the control from the generic Control type to its actual type To do that, you also need to add the@Referencedirective
to the page This tells ASP.NET to compile the user control and link it to the ASP.NET page so that the
page knows where to find the user control type Listing 26-7 demonstrates how you can access a custom property of your user control by casting the control after loading it The sample loads a modified user
control that hosts an ASP.NET TextBox control and exposes a public property that allows you to access the TextBox control’sTextproperty
Trang 10Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1200
Chapter 26: User and Server Controls
Listing 26-7: Casting a user control to its native type
VB
<%@ Page Language="VB" %>
<%@ Reference Control="~/WebUserControl.ascx" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myForm As Control = Page.FindControl("form1") Dim c1 As WebUserControl = _
CType(LoadControl("~/WebUserControl.ascx"), WebUserControl) myForm.Controls.Add(c1)
c1.ID = "myWebUserControl1"
c1.Text = "My users controls text"
End Sub
</script>
C#
<%@ Page Language="C#" %>
<%@ Reference Control="~/WebUserControl.ascx" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Control myForm = Page.FindControl("Form1");
WebUserControl c1 = (WebUserControl)LoadControl("WebUserControl.ascx");
myForm.Controls.Add(c1);
c1.ID = "myWebUserControl1";
c1.Text = "My users controls text";
}
</script>
Notice that the sample adds the control to the Form’sControlscollection and then sets theTextproperty
This ordering is actually quite important After a page postback occurs the control’s ViewState is not
calculated until the control is added to theControlscollection If you set theTextvalue (or any other
property of the user control) before the control’s ViewState, the value is not persisted in the ViewState
One twist to dynamically adding user controls occurs when you are also using Output Caching to cache
the user controls In this case, after the control has been cached, theLoadControlmethod does not return
a new instance of the control Instead, it returns the cached copy of the control This presents problems
when you try to cast the control to its native type because, after the control is cached, theLoadControl
method returns it as aPartialCachingControlobject rather than as its native type Therefore, the cast
in the previous sample results in an exception being thrown
To solve this problem, you simply test the object type before attempting the cast This is shown in
Listing 26-8
Listing 26-8: Detecting cached user controls
VB
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myForm As Control = Page.FindControl("form1") Dim c1 As Control = LoadControl("~/WebUserControl.ascx") myForm.Controls.Add(c1)
1200