The System.Web.UI.WebControls namespace contains a collection of classes that allow you to create Web server controls on a Web page. You can programmatically control the Web server controls because they run on the server.
Note | In addition to Web server controls, there is a mostly parallel hierarchy of controls in the System.Web.UI.HtmlControls namespace. The controls in the HtmlControls namespace provide a very thin layer on top of the native HTML controls. The HtmlControls namespace hierarchy is a little more lightweight than the WebControls namespace that I will describe here. However, the object model for the controls in the WebControls namespace is more consistent than it is for the controls in the HtmlControls namespace. The HtmlControls namespace very closely matches the underlying HTML controls, and the lack of consistency in the namespace is a result of the lack of consistency in the underlying HTML controls. Controls in the HtmlControls namespace have their place when no server-side postback updates are required. I have found no compelling reason to use any of the controls in the HtmlControls namespace in this book. |
To fully explain the controls in the WebControls namespace in a reasonable amount of time, it is best to first describe the base classes used for the controls in the WebControls namespace. A few simple controls inherit directly from System.Web.UI.Control, but the bulk of the controls inherit from a class that descends from System.Web.UI.Control named System.Web.UI.WebControls. First, let's look at System.Web.UI.Control.
System.Web.UI.Control is the base class for several simpler controls, such as Literal, Placeholder, Repeater, and Xml.
The declaration for the System.Web.UI.Control class is as follows:
public class Control : IComponent, IDisposable, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
This declaration says that the Control class implements eight interfaces (the names following the colon that begin with I). An interface is similar to a class, in that it declares properties, methods, and events. Unlike a class, however, an interface does not provide any implementation of the properties, methods, and events. An interface identifies operations that an object supports. When a class implements an interface (in C#, by providing the name of the interface after a colon following the class name), the class must provide implementation for every member of the interface. Interface implementation establishes a contract in which the class (and the Microsoft .NET Framework, in this case) ensures that the members of the interface are implemented in the class. If a new member is added to an interface, it should be added to a copy of the interface with a different name, and the existing interface must remain the same. This rule is not enforced by the .NET Framework; however, changing an interface will result in compile-time or run-time errors.
Note | Commonly, interface names begin with I. This is a standard convention rather than a requirement, but it makes sense to follow it. |
Of the eight interfaces implemented, a few are primarily for use in the Visual Studio Design view. Unrelated to these, the IDisposable interface is a common interface that provides a standardized way to ensure that any unmanaged resources are cleaned up without needing to wait for garbage collection to take place. Another interface, IComponent, is one that all components must implement to be used.
The most important members of the Control class (first properties, and then methods) are outlined in Table 2-1.
Member Name | Description |
---|---|
ClientID | A property that returns the ID of the HTML control rendered in the browser (as described in Chapter 1, "The Web Forms Environment"). Use this value to create JavaScript that will reference a Web Form control on the client. |
Controls | A property that gets a ControlCollection object that references the child controls (if any) for the specified control. |
EnableTheming | A property that gets or sets a value indicating whether themes apply to this control. Chapter 3, "Web Form Layout," covers Web Form layout in general, and specifically theming. |
EnableViewState | A property that gets or sets a value indicating whether the control persists its view state and the view state of any client controls to the requesting client. View state is maintained on the client for the current page and returned to the server with each posting. Disabling view state can greatly reduce the size of the page sent to the client. Many controls, however, do not function as expected with view state disabled. |
ID | A property that gets or sets the ID of the server control. Note that this ID is likely to be different from the ClientID property described previously. |
Page | A property that gets a reference to the Page instance on which the server control is contained. |
Parent | A property that gets a reference to the server control's parent control in the page control hierarchy. The parent of most controls will be the same as the Page property, but it could instead be a panel or some other control that contains other controls. |
Site | A property that gets information about the container that hosts the current control on the design surface. |
SkinID | A property that gets or sets the skin to apply to the control. Skins will be covered in Chapter 3. |
UniqueID | A property that gets the unique, fully qualified identifier for the server control. This is a property that in some ways is similar to the ClientID property, which allows you to safely reference a control in JavaScript, regardless of what container a control resides on. The UniqueID property does a similar thing for the server side. |
Visible | A property that gets or sets a value that indicates whether a server control is drawn (or rendered) in the browser. One less-than-obvious implication of setting the Visible property to false is that the control is not present at all in the HTML sent to the browser. So, if you have client-side code that references a control that is not visible, the client-side code will not be able to find the control because the control will not be rendered in the HTML. |
ApplyStyleSheetSkin | A method that applies the style properties defined in the page style sheet to the control. |
FindControl | A method that searches the current control for a specified server control. |
Focus | A method that sets input focus to a control. |
HasControls | A method that determines whether the server control itself contains any child controls. |
RenderControl | A method that outputs content and emits trace information, if tracing is enabled. |
Note | For all controls covered in this chapter, not every property or method is described in the tables. MSDN is the authoritative source for complete listings of class members. The tables presented in this chapter cover the most important of the properties for the purpose of this discussion. Although lists such as this can be tedious, I believe the abbreviated lists presented in this chapter will be of great assistance to developers moving to Web Forms development. Properties of controls on Web Forms can generally be set programmatically (in the code in Object.Property=value format) or declaratively (in the tags of the Web control). If you have any doubt about how to declaratively set properties in the Web control tags, set the properties in the Visual Studio Properties window, and then switch to Source view and look at the changes to the control. |
These properties and methods are present in all controls that inherit from System.Web.UI.Control, which includes all the controls in System.Web.UI.WebControls. The controls that derive directly from System.Web.UI.Control are described in the following sections.
The Literal control reserves a location for static text on a Web Form. Table 2-2 lists the one and only significant addition to what the Control class offers.
Member Name | Description |
---|---|
Text | Gets or sets the text to display in the Literal control. |
The Literal control is rarely used, because the Label control (described later in this chapter) is more often used to display static text. Of course, for static text, the Literal control is more efficient to use, since it does not maintain view state and results in somewhat more efficient HTML. I think that the preference for the Label control over the Literal control has to do with a developer's experience using label controls in other development environments and the relative placement of the Label control vs. the Literal control in the Visual Studio Toolbox. The Label control is the top control in the Toolbox, and the Literal control is much farther down. Where efficiency really matters, and where the text really is static, the Literal control is your best bet.
In Classic ASP, it was common to write out text using the Write method of the Response object. Why you would use the Literal control, rather than using Response.Write(), is explained in the following discussion of the PlaceHolder control.
The PlaceHolder control holds dynamically added server controls to the page at a particular location. You might wonder why such a control is required. In Classic ASP, when you added an HTML control to a page, you would often use Response.Write() to write out the HTML required for a new control. The problem with doing this in ASP.NET is best explained with an example.
I created a new project named Controls, which will be used by all examples in this chapter. To this project, I added a new Web page by right-clicking the Web site in Solution Explorer, selecting Add New Item from the context menu, selecting WebForm as the file type in the resulting dialog box, and naming the page WhyPlaceholder.aspx. I added nothing to the .aspx page in Design view, and I pressed F7 to access the source code for the page. Inside the Page_Load event handler, I added the following line of code.
Response.Write("<INPUT type='Submit' ID='btn' />");
The expected result is a page with a single button, as shown in Figure 2-1.
Figure 2-1: A page with a submit button added in the Page_Load event handler
So, if using Response.Write() results in a button on the page, why would we need a PlaceHolder control? There are two reasons. First, and most important, the control is not properly placed on the page. If you look at the source (click View in the browser, and then click Source), you will see the following.
<input type='submit' ID='btn'/> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head><title> Default Page </title></head> <body> <form method="post" action="WhyPlaceholder.aspx" > <div> <input type="hidden" name="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGS8kuieTjLiGMkER51KF6YNnBcsrw==" /> </div> <div> </div> </form> </body> </html>
The submit control is added at the top of the resulting source, not within the form inside the HTML code. Placing the button outside the form causes a few problems. In general, the form will not be submitted as you would want it to be. In a more complex page in which you place controls declaratively (by dragging the controls onto the form in Design view in Visual Studio), the button is not likely to be placed in the position you want. Even if you use a style attribute to force the control to be positioned visually in a particular location (something Iargue against in almost all cases browsers come in all shapes and sizes), the control will not be correctly placed logically in the structure of the page. In Classic ASP, code could be placed anywhere in the page, and it would be evaluated and run where it was placed as the page was evaluated, top to bottom. In contrast, all code in an .aspx page must be contained inside methods in classes, rather than simply where convenient. Because all code in ASP.NET is methods of classes, the code does not have any notion of location within the page.
A second, more important problem with inserting a control as I did in the WhyPlaceholder.aspx example is that the control as inserted is only a client-side control. There is no convenient way to access the contents or events of the control on postback. When you dynamically insert controls on a page, you generally want to insert a control you can access on the server side. The PlaceHolder control allows you to add server-side controls at the location of the PlaceHolder control. You can then interact with the control on the server side, as well as the client side.
With this background, I will describe in Table 2-3 one of the properties inherited by and used extensively with the PlaceHolder control.
Member Name | Description |
---|---|
Controls | A property that gets a ControlCollection object that references the child controls (if any) for the specified control. For the PlaceHolder control, more importantly, the .Add method of the Controls collection allows a developer to add controls at a specific location. |
To see the PlaceHolder control in action, I created a new Web Form named WhyPlaceholder2.aspx. I added a PlaceHolder control to the new page by dragging it from the Toolbox onto the form in Design view. Then I pressed F7 to open the code for the page and added the following lines to the Page_Load event.
System.Web.UI.WebControls.TextBox tb = new TextBox(); tb.ID = "tb"; tb.Text = "Hello World"; this.PlaceHolder1.Controls.Add(tb);
The two properties that I set here are not strictly required. However, you should usually set the ID property so that you can identify the control when handling a postback. Figure 2-2 shows the page with the preceding code adding the control.
Figure 2-2: A page with a text box added to a PlaceHolder control in the Page_Load event handler
More important than what the page looks like (Figure 2-1 looked OK in the browser), the HTML source sent to the browser is correct, placing the newly added control inside the form.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head><title> Default Page </title></head> <body> <form method="post" action="WhyPlaceholder2.aspx" > <div> <input type="hidden" name="__VIEWSTATE" value="/wEPDwUKMTUyNzUzNTM5OGRkv9jclrspkrNAsYfe3C3tJlF6RSU=" /> </div> <div> <input name="tb" type="text" value="Hello World" /> </div> </form> </body> </html>
Note that the PlaceHolder control, added in Design view, does not render any HTML. The text box (named tb, with text set to Hello World) is placed where the placeholder was in the .aspx page.
Note | The Literal control does for plain text what the PlaceHolder control does for server controls. Rather than using Response.Write() to add text to a page, dropping a Literal control on the page and adding the text to the .Text property allows a developer to control precisely where text will appear on the page. It is still possible to use the <%=variableName%> syntax to place text where you want it on the page, but it is not a good idea. Developers creating a framework, like the developers of ASP.NET, have in mind a specific programming model. If you want to add text and controls to a page, the Literal and PlaceHolder controls (respectively) are the way to go. |
The Repeater control is a data-bound control, often used in conjunction with tables, that allows the developer to specify a set of templates that control how a header, a footer, and items (and optionally, alternating items) appear. Table 2-4 describes the properties added to the Repeater control that are not included in the Control class that serves as the Repeater control's base.
Member Name | Description |
---|---|
AlternatingItemTemplate, ItemTemplate | Properties that get or set the System.Web.UI.ITemplate that determines how alternating items and items in the control are displayed. ITemplate is an interface that defines the behavior for populating a templated ASP.NET control (such as the Repeater control) with child controls. The ItemTemplate property defines the format and style to be used for each item on the page, unless an AlternatingItemTemplate property is defined in this case, the two templates are used for every other line. By using the ItemTemplate and AlternatingItemTemplate properties, you can, for instance, create a report in which alternating colors are used on each line for the text or the background. Although it is possible to manipulate these templates programmatically, they are almost always set declaratively on the .aspx page. |
DataBind | A method that binds the data source to the control. |
DataMember | A property that gets or sets the specific table in the data source to bind to the control. The data source provides the data used to feed the Repeater control. This property will be discussed in Chapter 5, "Data Binding." |
DataSource | A property that gets or sets the data source that provides data for populating the list. This must be set to an object that implements the IEnumerable or IListSource interface. |
DataSourceID | A property that gets or sets the ID property of the data source control that should be used to provide data to populate the list. If theDataSourceID property is set, the DataSource property must not beset, and vice versa. |
FooterTemplate, HeaderTemplate | Properties that get or set the System.Web.UI.ITemplate that determines how the footer (the bottom of the Repeater control) or header (the top of the Repeater control) in the control are displayed Although it is possible to manipulate these templates programmatically, they are almost always set declaratively on the .aspx page. |
Items | A property that gets the collection of RepeaterItem objects in the Repeater control. The RepeaterItem object represents one of the items to be rendered by the Repeater control. |
SeparatorTemplate | A property that gets or sets the System.Web.UI.ITemplate that defines how the separator between items is displayed. |
Imagine that you have a list of people and their pets. You want to create a list of sentences identifying these people and pets, but you don't want to manually read through the list and write out the sentences one by one. The Repeater control allows you to easily create a simple page like the one shown in Figure 2-3.
Figure 2-3: The Repeater control displaying people and their pets
To create this page, I added a new page to the Controls Web application named Repeater.aspx. I dragged a Repeater control onto the page in Design view, switched to Source view, and then added markup into the Repeater control, so that the code looked like the following.
<asp:Repeater runat="server"> <ItemTemplate> <font color=blue> <%#Eval("Name") %>'s Pet is named <%#Eval("Pet") %></font> </ItemTemplate> <AlternatingItemTemplate> <font color=red> <%#Eval("Name") %>'s Pet is named <%#Eval("Pet") %></font> </AlternatingItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> </asp:Repeater>
The <ItemTemplate> section defines what the items bound to the repeater look like. The <AlternatingItemTemplate> section allows you to describe (optionally) what alternating items look like. If you wanted to create a standard "gray bar" report, you could set a background using <AlternatingItemtemplate>. The <%#Eval(FieldName)%> syntax allows data-bound fields to appear in the item-related templates in the repeater. Generally, the <%# %> syntax is used to allow inline items to be data bound. The Eval() function allows the developer to access fields in the data source. In this example, the names of the fields are "Name" and "Pet." The <ItemTemplate> and <AlternatingItemTemplate> sections in this example use a different font color for alternating items. The <SeparatorTemplate> section in this example uses a simple horizontal rule tag to draw a line between items.
After the markup is entered, the next step is to enter some code. Pressing F7 brings you to the code file. A couple of steps are required to get the Repeater control working. First, an additional using clause must be entered.
using System.Collections.Generics;
Generics are a new feature in C# 2.0. Repeatedly developing the same object is a recurring problem for developers of all sorts of applications. Generics offer a way to create a class once and use that class with all sorts of objects. A common program requirement is to manage lists of items. Before C# 2.0 was available, developers could use an ArrayList object to manage collections of objects. The ArrayList class can contain any number of any objects. Unfortunately, if they intended to create an ArrayList object containing only names, it would be possible to do something like the following.
ArrayList al=new ArrayList(); al.Add("Doug"); al.Add("Tim"); al.Add(4);
The Add method expects an object to be passed in as a parameter; because all classes inherit from the object class, there is no restriction on what can be added to the ArrayList object. This code will compile, and it might even run, depending on what the code does later with the items in the ArrayList object. Generics offer a type-safe alternative.
The next step is to create a class to use to supply the Repeater control. Often, database results will act as the data source for repeaters, and binding to database results will be covered in Chapter 5. This example uses a list of objects named People. The People class should be added to the source file outside the page class. The People class is shown here.
public class People { private string _name; private string _pet; public People(string newName, string newPet) { _name = newName; _pet = newPet; } public string Name { get { return _name; } } public string Pet { get { return _pet; } } }
The People class is a simple class that exposes two properties, Name and Pet, as well as a public constructor that accepts two arguments used to initialize the properties.
Note | A property of a class allows the designer of the class to expose an object by using get and set methods, rather than by making an underlying data member public. More importantly, properties allow the designer of a class to expose a synthesized value, a value that does not actually exist directly in the underlying class. For instance, a class could contain private data members for the unit cost and quantity of a line of an order, and expose a LineTotal property that, when called, calculates the line total by multiplying quantity by unit cost. In other cases, properties can be used to allow lazy initialization. For instance, a class might have a property that is derived from a time-consuming database query. If the property is not needed, the database query will never be made. If the property is needed, it is calculated when needed (and perhaps cached for future use). The properties in the People class have only getters defined, and so the properties are read-only. |
The next step is to add some code to the Page_Load event handler to create the list of people and set that list as the DataSource property. The DataSource property on many controls specifies where the data for the control will come from. Most often, the DataSource property is set to a database-related data source, which will be discussed in Chapter 5. Here is the code.
List<People> peeps=new List<People>(); peeps.Add(new People("Doug","Sally")); peeps.Add(new People("Timothy","Boomer")); peeps.Add(new People("Erin","Cleo")); peeps.Add(new People("Jean", "Taffy")); this.Repeater1.DataSource=peeps; this.Repeater1.DataBind();
The List<T> class is one of the generic classes. When a generic class is described, <T> is used as a placeholder of any type. In the preceding code from the Page_Load event handler, the <T> is replaced by <People>, creating a list of people named peeps. Using the List<T> class, the.Add() method is type-safe and will only allow addition of objects of the correct type. The next four lines each add a new instance of the People class to the peeps list. The last two lines set the DataSource property of the Repeater class and call DataBind(), which sets the Items collection of the Repeater class.
Note | In the MSDN documentation for the WebControls classes, the Repeater control is not grouped with either the list controls or the data list controls, although arguably it might be grouped with either of these. |
The Xml control can be used to transform an XML document using Extensible Stylesheet Language Transformations (XSLT). The Xml control also inherits directly from the System.Web.UI.Control class. Some additional properties and methods are added to the Xml control, and the important ones are described in Table 2-5.
Member Name | Description |
---|---|
DocumentContent | A property that sets a string that contains the XML document to display in the Xml control. |
DocumentSource | A property that gets or sets the path to an XML document to display in the Xml control. |
Transform | A property that gets or sets the path to the XSLT transform object that formats the XML document before it is written to the output stream. |
TransformArgumentList | A property that gets or sets a list of optional arguments passed to the style sheet used for XSLT. |
TransformSource | A property that gets or sets the path to an XSLT style sheet that formats the XML document before it is written to the output stream. |
The Xml control is commonly used to take an XML document and transform it using an XSLT style sheet. For example, an XML document might contain information on a menu and the URLs the menu items refer to, and the XSLT style sheet will transform that information into appropriate HTML to display a menu.
The bulk of Web controls derive from the System.Web.UI.WebControl class. The WebControl class derives from the Control class, and so do all of the properties and methods mentioned in the preceding section on the System.Web.UI.Control class. Most of the properties added in the WebControl class fall into two categories: properties that assist with a control gaining focus, and properties that control the appearance of the control. These are described in Table 2-6.
Member Name | Description |
---|---|
AccessKey | A property that gets or sets the access key that allows you to quickly set focus on the control. |
Attributes | A property that gets a collection of arbitrary attributes that can be added to the rendered client control. For instance, a bad use of this collection is to add a Value attribute to a text box control set to Password mode. Text boxes in Password mode do not allow default text (because of the security risk), but by using the Attributes property, you can overcome this limitation. But you should not! |
BackColor, BorderColor, BorderStyle, BorderWidth, Font, ForeColor, Height, Style, Width | Properties that control the appearance of the control, as you would expect. The Font property is a complex data type that describes all aspects of the font, and the Style property is a collection of text attributes to be rendered as the style attribute of the outer HTML control. |
CssClass | A property that gets or sets the cascading style sheet class. More information is provided in Chapter 3. |
Enabled | A property that gets or sets a value indicating whether the control is enabled. Disabled controls are commonly displayed so that it is apparent that they are disabled. |
EnableTheming | A property that gets or sets a value indicating whether themes will apply to this control. |
TabIndex | A property that gets or sets the tab index of the control. This defines the order in which controls will be visited as the user presses the Tab key. Generally, using the default order (left to right, top to bottom) is best. |
ToolTip | A property that gets or sets text used for the ToolTip, which appears in a popup window when the mouse rests on the control. |
A couple dozen controls derive directly or indirectly from the WebControl class. I will cover the majority of those controls in this section, omitting the table-related controls and the AdRotator control.
Almost every page will have a button, and the Button control is used on virtually every example in this book. Traditionally, Web applications required a button to initiate a postback. With creative use of JavaScript, all sorts of controls can now cause a postback, but the button is still the most frequently used. Table 2-7 describes the additional properties, methods, and events of the Button control that are not included in the WebControl class.
Member Name | Description |
---|---|
CausesValidation | A property that gets or sets a value that controls whether the button causes validation. Validator controls (discussed later in this chapter) can prevent submission of a form with invalid or incomplete information. This is not always the right thing to do; for instance, a Cancel button should not check for correct and complete entries. |
CommandName | A property that gets or sets the name passed to the Command event. |
OnClientClick | A property that gets or sets the client-side script that will be executed on the client when the button is clicked. |
PostBackUrl | A property that gets or sets the URL of the page to post back towhen the button is clicked. ASP.NET 1.x did not allow postbacks to a different page, but ASP.NET 2.0 does. This is a feature that I have seldom found useful, because I prefer to have all the logic associated with a particular page on that page. All example pages in this book will post back to themselves. |
Text | A property that gets or sets the text for the button caption. Text is a property common to many controls that derive from the WebControl class. |
UseSubmitBehavior | A property that gets or sets a value indicating whether the button uses the client browser's submit mechanism or the ASP.NET framework. If true, the standard HTML submit behavior is used; if false, JavaScript is used. |
ValidationGroup | A property that gets or sets the group of controls for which the button causes validation. In ASP.NET 1.1, all validators were fired for any form submission. ASP.NET 2.0 allows the developer to assign each button to a group of validators so that multiple zones on the form can be validated independently. For instance, a singleWeb Form with a set of controls that allows a user to log in and register can validate the control sets separately, depending on whether the Login or Register button is clicked. |
Click, Command | Events fired when the button is clicked. |
The Checkbox control is used to select a true or false value. The Checkbox control is usually rendered as a box that toggles a check mark in the box when clicked. Multiple check boxes are often used together to allow selection of multiple, non-exclusive items. Often, the CheckBoxList control, described later in this chapter, is more appropriate for creating multiple check boxes that should act as a single group. Table 2-8 shows significant Checkbox control members.
Member Name | Description |
---|---|
AutoPostback | A property that gets or sets a value that controls whether the check box automatically posts back when the control is clicked. Many of the controls that derive from the WebControl class contain an AutoPostback property. Note that the AutoPostback behavior is dependent on JavaScript working on the client. |
Checked | A property that gets or sets a value indicating whether the check box is selected. |
Text | A property that gets or sets the text associated with the check box. |
TextAlign | A property that gets or sets a value from the TextAlign enumeration, either Left or Right, indicating whether the text should appear to the left or right of the check box. |
CheckedChanged | An event fired when the checked state of the control is changed. This event is fired immediately if AutoPostback is true and the client browser supports JavaScript. |
The RadioButton control inherits directly from the Checkbox control, so the two controls are similar and share the properties and event shown in Table 2-8. The RadioButton control is often rendered as a circle, and when clicked, a dot inside the circle toggles. When two or more radio buttons (also called option buttons) are placed together, any currently selected button is deselected when any one of the buttons is clicked. The action is similar to the mechanical buttons used on car radios in the 1970s and earlier, hence the name. Often the RadioButtonList control, described later in this chapter, is more appropriate for creating multiple radio buttons that should act as one.
The HyperLink control creates a link on a Web page, commonly used to allow a user to jump to another page. Table 2-9 shows the important members of the Hyperlink control class.
Member Name | Description |
---|---|
ImageUrl | A property that gets or sets a URL to use for an image when an image link is desired over a text link. |
NavigateUrl | A property that gets or sets the URL that the user will navigate to when the HyperLink control is clicked. |
Text | A property that gets or sets the text for the HyperLink control. If both the Text property and the ImageUrl property are set, the ImageUrl property will prevail, and the image will be displayed rather than the text specified in this property. |
The Image control allows you to display an image on the page. Table 2-10 introduces significant members of the Image control class.
Member Name | Description |
---|---|
AlternateText | A property that gets or sets text to display when the image is unavailable. Alternate text is especially useful for visually impaired users. |
ImageUrl | A property that gets or sets a URL to use for the image that you want to display. |
The ImageButton control's base class is the Image control just described. The ImageButton control is rendered much like an Image control, and it behaves in a way that might seem similar to the HyperLink control. The difference is that rather than redirecting the user to another page, the ImageButton control causes a post back to the page on which the control resides. The ImageButton control does this by using JavaScript; if JavaScript is disabled, or if the underlying JavaScript is in some way broken, the ImageButton control will not work.
Note | How big of a problem is this? For me, it sometimes can be a major problem. For instance, I have a weblog at http://weblogs.asp.net/dreilly. This is a wonderful site, and it provides me with a free place to host my thoughts on all things computer related. Unfortunately, I cannot administer the site from my Pocket PC (something that is often quite convenient) because the site uses some variation on an ImageButton control for its login page. And even though the Pocket PC supports JavaScript, it seems not to like the specific JavaScript used on the login page. |
Table 2-11 introduces the important members of the ImageButton control class.
Member Name | Description |
---|---|
AlternateText | A property that gets or sets text to display when the image is unavailable. Alternate text is especially useful for visually impaired users. |
CausesValidation | A property that gets or sets a value that controls whether the button causes validation. Validator controls (discussed later in this chapter) can prevent submission of a form with invalid or incomplete information.This is not always the right thing to do; for instance, a Cancel button should not check for correct and complete entries. |
CommandArgument, CommandName | Properties that can be set to allow a single event handler to manage multiple ImageButton OnClick events. The CommandName and CommandArgument properties can be set to allow the single OnClick event to determine the source of the click. |
Click, Command | Events fired when the ImageButton control is clicked. |
The Label control is used to display text in a way very similar to the Literal control previously described. The distinction between the Label and the Literal controls is primarily that the Label control contains the properties that it inherits from the WebControl class for greater control over the appearance of rendered text.
The Panel control acts as a container for other controls. Using a Panel control allows you to control the visibility of a group of controls at once. This can be useful when you select an option on a form that might require entry of additional fields. The panel can be made visible or invisible based on an entry in another field. A few significant properties are added by the Panel control, as described in Table 2-12.
Member Name | Description |
---|---|
BackgroundUrl | A property that gets or sets the URL of an image to be used as the background of the Panel control. |
DefaultButton | A property that gets or sets the button to be used as the default button. The default button is the button to be clicked when the Enter key is pressed. This property is also available for the form as a whole. |
GroupingText | A property that gets or sets text to be used as the title for a group box to appear around the Panel control. |
HorizontalAlign | A property that gets or sets a value to align text in the Panel control. The value must be from the HorizontalAlign enumeration: Center, Justify, Left, NotSet, or Right. The default is NotSet. |
ScrollBars | A property that gets or sets a value to control the appearance of scroll bars on the Panel control. The value must be from the ScrollBars enumeration: Auto, Both, Horizontal, None, or Vertical. The default is None. |
Wrap | A property that gets or sets a Boolean value indicating whether content in the panel should wrap. |
The workhorse of the Web controls is the TextBox control. The TextBox control allows the user to enter text, and it can be rendered as a simple text box, as a multiline text box (an HTML TextArea control), or a password text box. Several properties are added by the TextBox control, as described in Table 2-13.
Member Name | Description |
---|---|
AutoCompleteType | A property that gets or sets a value indicating the type of automatic completion that should occur. The value must be one of the AutoCompleteType enumeration values. There are a large number of values, documented in the MSDN documentation. For example, if you enter "Douglas Reilly" in a TextBox control where the AutoCompleteType property is set to DisplayName, the next time you enter a value into a text box with AutoCompleteType set to DisplayName, Microsoft Internet Explorer will offer "Douglas Reilly" as an option in the autocomplete drop-down list. |
AutoPostBack | A property that gets or sets a Boolean value indicating whether the page should be posted back whenever the text is changed and the user leaves the field. Note that this relies on JavaScript being active, and an event handler for the TextChanged event should be defined (more on the TextChanged event is provided at the end of this table). |
Columns | A property that gets or sets the width, in characters, of the text box. Note that the MaxLength property actually sets the maximum number of characters that can be entered into the text box. |
ReadOnly | A property that gets or sets a Boolean value that controls whether the TextBox control should be rendered as read-only (not allowing modification).Sometimes it is useful to display static text in a text box rather than as part of a label. |
Rows | A property that gets or sets an integer value indicating the number of rows in a multiline TextBox control. See the TextMode property for more information on creating a multiline text box. |
Text | A property that gets or sets a string to be displayed in the TextBox control. |
TextMode | A property that gets or sets a value indicating the type of text box that should be rendered. This must be one of the values in the TextBoxMode enumeration: MultiLine, Password, or SingleLine. SingleLine is the default, and it renders as a traditional text box. MultiLine renders as an HTML TextArea control rather than an Input control, and MaxLength is not honored. When the TextMode property is set to Password, characters entered are echoed as asterisks. Also, the Text property is not rendered to the browser, because the text would appear in plain text in the browser. This can be overcome by explicitly setting an attribute of the TextBox control, but this is not recommended. |
Wrap | A property that gets or sets a Boolean value indicating whether text should wrap in a multiline text box. |
TextChanged | An event fired when the text in a TextBox control is changed and the user leaves the control. Note that this method is generally only useful when the AutoPostBack property is true. |
Note | The Panel and TextBox controls both expose a Wrap property. These properties are independently implemented in both of these controls, but they do point out an important reason why using the controls in the WebControls namespace is preferable to using the controls in the HtmlControls namespace. The controls in the WebControls namespace provide a more consistent object model; properties that do the same thing have the same name. The HtmlControls programming model merely mimics the underlying HTML tags and therefore has very little consistency from a programming model perspective. |
A common requirement for any data entry screen, whether Web Form or Microsoft Windows Form, is date entry. The Calendar control displays a single month at a time, and it allows the user to navigate between months. The Calendar control exposes several new properties, as described in Table 2-14.
Member Name | Description |
---|---|
Caption | A property that gets or sets a string to be used as a caption, or title, for the calendar. |
CaptionAlign | A property that gets or sets a value indicating the alignment of the caption. The value must be a member of the TableCaptionAlign enumeration: Bottom, Left, NotSet, Right, or Top. NotSet is the default. |
CellPadding | A property that gets or sets a value indicating the amount of space between the content and the border of the cell. |
CellSpacing | A property that gets or sets a value indicating the amount of space between cells. |
DayHeaderStyle, DayStyle, NextPrevStyle, OtherMonthDayStyle, SelectedDayStyle, SelectorStyle, TodayDayStyle, WeekendDayStyle | Properties that get or set the style indicated, which is of type TableItemStyle. The names of the properties are self explanatory, with the possible exception of OtherMonthDayStyle, which is used to control the appearance of days in a month other than the currently selected month. Commonly, these styles are set in the Visual Studio editor, and there are even predefined color schemes that will be explained shortly. |
DayNameFormat | A property that gets or sets a value indicating how day names should be presented. The value must be a member of the DayNameFormat enumeration: FirstLetter, FirstTwoLetters, Full, Short, or Shortest. For U.S. English, FirstTwoLetters, Short, and Shortest all produce the same day formats. |
FirstDayOfWeek | A property that gets or sets a value indicating what should appear as the first day of the week. The value must be a member of the FirstDayOfWeek enumeration, which includes each day of the week as well as Default, which uses system settings to control the first day of the week. |
NextMonthText, PrevMonthText | Properties that get or set a string that is displayed for the Next or Prev month navigation control. The default values are > and <, respectively, which render in a browser as > and <, respectively. |
SelectedDate | A property that gets or sets the currently selected date as a DateTime object. |
SelectedDates | A property that gets a collection of DateTime objects that are currently selected. The SelectionMode property determines whether more than a single date can be selected and whether any dates at all can be selected. |
SelectionMode | A property that gets or sets a value indicating the mode used for selecting dates. The value must be a member of the CalendarSelectionMode enumeration: Day, DayWeek, DayWeekMonth, or None. DayWeek allows selection of a day or a week, and DayWeekMonth allows selection of a day, week, or month. |
SelectWeekText, SelectMonthText | Properties that get or set a string used for the link to select a week or month. |
ShowDayHeader, ShowGridLines, ShowNextPrevMonth, ShowTitle | Properties that get or set a Boolean value indicating whether the indicated items should appear in the rendered Calendar control. |
TitleFormat | A property that gets or sets a value indicating the format for the title of the calendar control. The value must be a member of the TitleFormat enumeration: Month or MonthYear (for instance, "January" or "January 2006"). |
TodaysDate | A property that gets or sets the DateTime object representing a specific date that appears as today's date. |
VisibleDate | A property that gets or sets the DateTime object that controls which month is currently visible. |
SelectionChanged, VisibleMonthChanged | Event handlers fired when the selection or the visible month are changed. |
The Calendar control, although not the most complex control (that honor goes to the GridView control, covered in Chapter 5), is the most complex single control covered in this chapter. One of the good things about using the Calendar control, however, is that when using Visual Studio you do not need to know all the details of how styles are set.
Perhaps the coolest new feature of Visual Studio 2005 is the availability of "smart tags" that allow you to perform common tasks on the complex controls. For instance, if you click the right arrow on the right side of the Calendar control, a menu appears with tasks specific to the control, as shown in Figure 2-4.
Figure 2-4: The Calendar Tasks menu in Visual Studio 2005
If you click Auto Format on the menu, a dialog box similar to the one shown in Figure 2-5 appears.
Figure 2-5: The Auto Format dialog box for the Calendar control
If you select Simple from the list of schemes on the left, the sample calendar appears more like the one shown in Figure 2-6.
Figure 2-6: The Auto Format dialog box with a scheme applied to the Calendar control
Each of the preset formats presents a different look, allowing a developer to easily change the appearance of a Calendar control quickly, without needing to know all the details of the control styles.
The ListControl class is an abstract class that acts as a base for all list controls. An abstract class is a class that is incomplete, with at least one method that has no implementation, and thus cannot be directly instantiated or used. List controls are an important element of most applications. Often list controls are bound to a database table or view. A more detailed discussion of data binding will be deferred until Chapter 5. Still, the descendants of the ListControl class can be useful even in the absence of a bound data source.
Note | Several interesting and important properties are exposed in the ListControl class that are related to data binding. Those properties are common to many data-bound controls and will be covered in Chapter 5. |
Table 2-15 explains the significant new properties and events exposed by the ListControl class.
Member Name | Description |
---|---|
Items | A property that gets the collection of items in the ListControl class. Each element in the collection is of type ListItem. Common properties of ListItem are Selected, Text, and Value. |
SelectedIndex | A property that gets or sets the index of the selected item. |
SelectedItem | A property that gets the first selected item in the Items collection. Some list controls allow multiple selection. |
SelectedValue | A property that gets the value (a string) of the first selected item in the Items collection. |
SelectedIndexChanged | An event that is fired whenever the selected index is changed. The SelectedIndexChanged event is often used in conjunction with the AutoPostBack property to allow the page to change as a result of the selected item changing. |
ClearSelection | A method that clears the Selected property of all the ListItem objects in the Items collection. |
Again, ListControl is an abstract base class for other non-abstract list controls that can actually be instantiated. Descriptions of those controls follow.
The DropDownList control, which descends directly from the ListControl abstract class, appears in the browser to be similar to the ComboBox control used in Windows Forms applications. The similarity is superficial, however. Unlike the ComboBox control, which can allow entry of arbitrary text into the text box at the top of the control when so configured, the DropDownList control only allows selection of an item from the list. ComboBox controls often allow incremental searches as well. So, if I enter "R" in one of these ComboBox controls, the list advances to the first entry starting with "R." If I type "e," the list advances to the first entry starting with "Re," and so on. Enter the same characters in the DropDownList control, and the list moves to the first name starting with "e" as I type "e," ignoring the previously entered "R." The only properties added by the DropDownList control are BorderColor, BorderStyle, and BorderWidth, which do exactly what you would expect.
The ListBox control is similar to the DropDownList control. The ListBox control looks like the bottom portion of the DropDownList control when the list is showing. ListBox is a control that can be used when multiple selections are required. Multiple selections can be made using Ctrl+Click and Shift+Click actions, exactly as with standard Windows controls. Ctrl+Click allows selection of random items in a list, and Shift+Click allows selection of a region of the list. The ListBox control adds a single significant property, described in Table 2-16, that is not already included in the DropDownList control.
Member Name | Description |
---|---|
SelectionMode | A property that gets or sets a value indicating how selections can be made in the ListBox control. The value must be a member of the ListSelectionMode enumeration: Multiple or Single. |
The DropDownList and ListBox controls are convenient, and the DropDownList control is relatively efficient in terms of use of space on a Web Form. One awkward aspect of the ListBox control is how multiple selections are made, relying on mouse clicks and Shift key combinations. The next two controls described offer an alternative to single and multiple selection of items.
The RadioButtonList control provides a convenient way to display a list of mutually exclusive choices. Using a RadioButtonList control is much more convenient than adding several option button controls together on a form. Table 2-17 describes some of the properties of the RadioButtonList control that are not included in the ListControl base class.
Member Name | Description |
---|---|
CellPadding | A property that gets or sets the distance, in pixels, between the border and the contents of the table cell. |
CellSpacing | A property that gets or sets the distance, in pixels, between adjacent cells. |
RepeatColumns | A property that gets or sets the number of columns used to display items. |
RepeatDirection | A property that gets or sets a value indicating the direction of the repeating columns. The value must be a member of the RepeatDirection enumeration: Horizontal or Vertical. |
RepeatLayout | A property that gets or sets a value indicating the way items should be laid out. The value must be a member of the RepeatLayout enumeration: Flow or Table. |
TextAlign | A property that gets or sets a value indicating the position of text with respect to the option button. The value must be a member of the TextAlign enumeration: Left or Right. |
The CheckBoxList control provides a convenient way to display a list of choices that allow selection of multiple items. Using a CheckBoxList control is much more convenient than adding several Checkbox controls together on a form. The CheckBoxList control adds the same additional properties as the RadioButtonList control.
RadioButtonList and CheckBoxList Example Although very often the RadioButtonList and CheckBoxList controls are populated from databases (which will be covered in Chapter 5), you can also add items manually to each of the controls.
In Visual Studio, in the Controls solution, I added a page named RadioAndCheckBoxLists.aspx. Then I added a RadioButtonList control, a CheckBoxList control, and labels. As in the Calendar example, both controls display a smart tag that allows you to select common tasks from a list, as shown in Figure 2-7.
Figure 2-7: The RadioButtonList Tasks menu in Visual Studio 2005
In the Tasks list for both controls is an Edit Items option that opens the dialog box shown in Figure 2-8.
Figure 2-8: The dialog box for editing items in Visual Studio 2005
Figure 2-8 shows the result of clicking Add four times. You should set the Text and Value properties for each item, because the defaults are not what you want to use. Figure 2-9 shows both the RadioButtonList and CheckBoxList controls with several items entered. The CheckBoxList control has its RepeatColumns property set to 2 and its RepeatDirection property set to Horizontal.
Figure 2-9: The RadioAndCheckBoxLists.aspx page
Using validators is an important part of developing Web Forms. One of the tedious aspects of traditional Web Forms development is checking values entered by the user. It is easy to validate most data entered, but forgetting to do so is even easier. Validator controls allow the developer to declaratively set up validation checks. The BaseValidator class is an abstract class that all validators inherit from; it inherits from the Label control and implements the IValidate interface. The significant members added by the BaseValidator class are described in Table 2-18.
Member Name | Description |
---|---|
ControlToValidate | A property that gets or sets the name of the control that the validator validates. |
Display | A property that gets or sets a value indicating how the validator should be displayed. The possible values are from the ValidatorDisplay enumeration. The values are None (meaning no display, ever), Dynamic (meaning that the validation text takes up no space on the form unless the text is visible), and Static (meaning that the validation text takes up space on the form whether or not the validation has failed, and the text is visible). None may seem unusual, but when used in conjunction with the ValidationSummary control, it can be a reasonable option. |
EnableClientScript | A property that gets or sets a Boolean variable indicating whether the validation should occur on the client, presuming client validation is even possible (this depends on whether JavaScript is available on the client). For this reason, and because a user intending damage could intentionally bypass the client-side validation, client-side validation should not be solely relied on. More information on this is included in the validation example later in this chapter. |
ErrorMessage | A property that gets or sets the text for the error message. |
IsValid | A property that gets or sets a Boolean value indicating whether the ControlToValidate property contains valid content. |
SetFocusOnError | A property that gets or sets a Boolean value indicating whether the ControlToValidate property should gain focus when there is an error. |
Text | An overridden property used to display text when the ControlToValidate property is invalid. Note that this is the text that appears at the site of the validator, and the ErrorMessage property is the text that will appear in a ValidationSummary control (described later). |
ValidationGroup | A property that gets or sets the validation group of the validator. Note that this can be any arbitrary string, and if non-blank, should probably match the validation group of some control that causes a postback, such as a Button or ImageButton control. |
Validate | A method that performs the validation on the ControlToValidate property and updates the IsValid property. |
The BaseCompareValidator class is derived directly from the BaseValidator class, and like BaseValidator, it is an abstract class. The BaseCompareValidator class acts as the base class for all typed comparison validators. It adds properties to allow for comparisons of multiple controls, or even just a comparison against a particular type, such as a date. The one significant property added by the BaseCompareValidator class is described in Table 2-19.
Member Name | Description |
---|---|
Type | A property that gets or sets a value indicating the type of data that the entered text should be evaluated as. The value must be a member of the ValidationDataType enumeration. The values are Currency, Date, Double, Integer, and String. The default value is String. Note that the comparison is performed on the server, and thus uses the server's locale for dates and currency unless the developer makes special allowances. |
Comparisons are evaluated in a type-dependent manner. For example, "5/1/2005" would be greater than "7/24/2004" if the Type parameter were set to Date, but evaluation would be reversed if the Type parameter were set to String.
Of course, BaseCompareValidator is an abstract class that cannot be used directly. So that you can create your own control that inherits from the BaseCompareValidator class, the CompareValidator control is provided in the standard set of Web controls.
The CompareValidator control is a flexible validator that can be used in a variety of ways, such as the following:
To validate that an entered value is of a particular type
To validate that an entered value has a relationship to some literal value specified
To validate that an entered value has a relationship to some other control
To do all this, several properties are added to the CompareValidator control that are not included in the class it inherits from, BaseCompareValidator. The significant added properties are shown in the Table 2-20.
Member Name | Description |
---|---|
ControlToCompare | A property that gets or sets the name of the control to compare with the control specified by the ControlToValidate property. Note that in some cases, you could just swap the values in ControlToValidate and ControlToCompare and invert the operator specified, and the program would still work as expected. However, it is generally better to have ControlToValidate as the later control in the tab order of the form so that the validator will be fired when the last control is exited. |
Operator | A property that gets or sets a value specifying the operation that should take place when the comparison takes place. It must be one of the values in the ValidationCompareOperator enumeration. The allowable values are Equal, NotEqual, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, and DataTypeCheck. If DataTypeCheck is specified, the ControlToCompare and ValueToCompare properties are ignored. |
ValueToCompare | A property that gets or sets a literal value that is used to compare against the value entered in the control specified by the ControlToCompare property. If the ValueToCompare and ControlToCompare properties are both set, ControlToCompare is used and ValueToCompare is ignored. |
Although the CompareValidator control and the other validator controls (described in the following sections) can perform an amazing number of validations, some validations cannot be performed easily, or at all, with the standard validators. The CustomValidator control was created for just such a situation.
For instance, imagine that you are allowing only new values (not currently in a database) to be entered into a field. You cannot possibly validate against the database directly by using a CompareValidator control, and none of the other standard validators will help in this case. The CustomValidator control allows you to specify a client-side and server-side event to be fired to validate a control. This example (validating that an entered value is not in the database) generally requires server-side logic.
New properties and events in the CustomValidator control are outlined in Table 2-21.
Member Name | Description |
---|---|
ClientValidationFunction | A property that gets or sets the name of the validation function to beccalled on the client to test input for validity. Note that this function will generally be a JavaScript function, and it must be available on the client. |
ValidateEmptyText | A property that gets or sets a Boolean value indicating whether empty text should be validated. This corrects a problem with the ASP.NET 1.x CustomValidator control, which is not called to validate empty controls. |
ServerValidate | The event fired on the server when validation is called for. The event handler accepts two parameters, one the Sender (which is the source of the event and is passed as an Object, the base type for all objects in .NET), and one of type ServerValidateEventArgs. The server validation event handler must set the .IsValid property of the ServerValidateEventArgs parameter. |
The RangeValidator control validates that an entered value is within a specified range. Validation is dependent on the setting of the Type parameter. Table 2-22 shows the two significant members added by the RangeValidator control class.
Member Name | Description |
---|---|
MaximumValue, MinimumValue | Properties that get or set the maximum and minimum values to use for range validation. |
Many types of input can be validated based on the pattern of characters entered. Examples of such input include telephone numbers, U.S. Social Security numbers, Zip Codes and Postal Codes, and so on. Regular expressions are a pattern against which a specific string is compared, and if the string doesn't match the pattern, the string is rejected. Regular expressions are incredibly versatile, but a detailed tutorial is well beyond the scope of this text. Fortunately, Visual Studio provides a tool with standard regular expressions already loaded, such as the following:
French phone number: (0(\d|\d))?\d\d\d\d(\d\d|\d\d)\d\d
Internet e-mail address: \w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
U.S. Zip Code: \d{5}(-\d{4})?
In the simplest example, the U.S. Zip Code, looking from left to right, the regular expression expects digits ("\d"), five of them ("{5}"), followed by zero or one occurrences ("?") of a dash and four digits ("(-\d{4})").
The RegularExpressionValidator control has the BaseValidator control as its base class, and it adds one significant property, shown in Table 2-23.
Member Name | Description |
---|---|
ValidationExpression | A property that gets or sets a string representing the regular expression used to validate the control. |
A common cause of confusion when using validators is that most validators will not fire unless the ControlToValidate property has some text entered. One noteworthy exception in ASP.NET 2.0 is the CustomValidator control, which provides a ValidateEmptyText property. Because of this, in many cases two validators (a RequiredFieldValidator control and some other validator) are required to correctly validate entries. A single property, described in Table 2-24, is new in the RequiredFieldValidator control.
Member Name | Description |
---|---|
InitialValue | A property that gets or sets a string representing initial value of the ControlToValidate property. By using the InitialValue property, you can have a RequiredFieldValidator control validate a control with an initial text value (for instance, "Enter a Number") that is considered the same as an empty field. |
One option for the Display property that all validation controls have is None, meaning that nothing will ever display in the validation control. This may seem useless, but sometimes it is best to display a validation message someplace other than right next to the control being validated. For instance, a Web Forms are displayed using a markup language, so precise control is not always easy or possible.
The solution is to use a ValidationSummary control. This control, unlike the other validation controls, inherits from the WebControl class. The ValidationSummary control can display text on the form or, where possible, in a message box with the validation errors. The ValidationSummary control adds several significant properties, shown in Table 2-25, to those in the base class, WebControl.
Member Name | Description |
---|---|
DisplayMode | A property that gets or sets a value indicating the display mode of the ValidationSummary control. This value must be a member of the ValidationSummaryDisplayMode enumeration. The allowed values are BulletList, List, and SingleParagraph. |
EnableClientScript | A property that gets or sets a Boolean value indicating whether clientscript should be used to display the validation summary. |
HeaderText | A property that gets or sets a string to use as the header for the validation summary. |
ShowMessageBox | A property that gets or sets a Boolean value indicating whether a message box on the client side should appear. |
ShowSummary | A property that gets or sets a Boolean value indicating whether the validation summary should appear inline on the page. |
Perhaps the best way to understand how all of these validators work is to look at an example. In this example, there is only a single line of actual code involved, in this case to set the date on a CompareValidator control to allow only dates earlier than today.
In the Visual Studio project called Controls (used for all examples in this chapter, and included with the code for the book), I added a Web Form named Validators.aspx that ultimately appeared as shown in Figure 2-10.
Figure 2-10: The Validators.aspx Web Form in Design view in Visual Studio
Note | This form is laid out using line breaks between the labels and the data entry controls. However, there are better ways to lay out a Web Form, and they will be covered in Chapter 3. |
To create this form, I dragged a label onto the form, positioned the cursor to the left of the label, pressed Enter, and then add the TextBox and RequiredFieldValidator controls on the next line. I changed the Text property of the label to display the text seen on the screen ("The Following Field (TextBox1) is Required") using the Properties window. Then I clicked the RequiredFieldValidator control and modified the following properties:
ControlToValidate: TextBox1
ErrorMessage: "TextBox1 Must Be Filled In"
SetFocusOnError: True
Text: "*"
I repeated the addition of the label and text box, modified the label text as shown in Figure 2-10, and then added a CompareValidator control. On the CompareValidator control, I modified the following properties:
ControlToValidate: TextBox2
ErrorMessage: "TextBox2 Must Be a Date Earlier Than Today"
Operator: LessThan
SetFocusOnError: True
Text: "*"
Type: Date
The changes to the properties of the CompareValidator control are designed to allow TextBox2 to be compared to a date, but note that I did not set the ValueToCompare property in the Visual Studio Properties window. Because I want the date entered to be earlier than today (whatever that date might be), I cannot set the date in the tab I have to set it in code. In the Page_Load event of the form, I added the following line of code:
this.CompareValidator1.ValueToCompare = DateTime.Today.ToShortDateString();
Using this one line of code, the ValueToCompare property will always be set to today's date, formatted as a short date string (mm/dd/yyyy in the U.S.). Setting the Operator property to LessThan causes the validator to look for a date less than (in the case of a date, earlier than) today.
I repeated the addition of the label and text box, modified the label text as shown in Figure 2-10, and then added a RegularExpressionValidator control. On the RegularExpressionValidator control, I modified the following properties:
ControlToValidate: TextBox3
ErrorMessage: "TextBox3 Must Be a US Zip Code"
SetFocusOnError: True
Text: "*"
ValidationExpression: \d{5}(-\d{4})?
I repeated the addition of the label and text box, modified the label text as shown in Figure 2-10, and then added a RangeValidator control. On the RangeValidator control, I modified the following properties:
ControlToValidate: TextBox4
ErrorMessage: "TextBox4 Must Be an Integer Between 1 and 10"
MaximumValue: 10
MinimumValue: 1
SetFocusOnError: True
Text: "*"
Next I added a label, a text box label, a second text box, and a CompareValidator control on the next line. I modified the labels as shown in Figure 2-10. On the CompareValidator control, I modified the following properties:
ControlToCompare: TextBox5
ControlToValidate: TextBox6
ErrorMessage: "TextBox5 Must Be Later than TextBox6"
Operator: GreaterThan
Type: Date
SetFocusOnError: True
Text: "*"
The final data entry and validation control set was entered in much the same way as the first four sets, but rather than adding a text box, I added a drop-down list with a RequiredFieldValidator control. I modified several properties of the RequiredFieldValidator control:
ControlToValidate: DropDownList1
ErrorMessage: "DropDownList1 Must Have a Value Selected"
InitialValue: "--Please Select--"
SetFocusOnError: True
Text: "*"
ValidationGroup: DDL
The RequiredFieldValidator control ensures that a value is selected in the drop-down list. For this to work, I needed to enter at least two items into the Items collection of the DropDownList control, using the Collection Editor dialog box shown in Figure 2-8. It is important that the initial item (or the item set as the default value, if it is not the initial item) has a value that exactly matches the InitialValue property of the RequiredFieldValidator control. In this case, I added the list items "--Please Select--," "Red," "Green," and "Blue."
Note | I will often set the InitialValue property programmatically, rather than declaratively, by using the SelectedText property. This ensures that if the initial value changes, my code will continue to work. |
Setting the ValidationGroup property to DDL allows the DropDownList control to be validated separately from the other controls on the page.
On a new line of the form, I added three buttons with the text values "Submit," "Cancel - Will Not Validate" (with the CausesValidation property set to False), and "Validate DropDownList1 Only" (with the ValidationGroup property set to DDL, the same as the ValidationGroup property of DropDownList1).
On the bottom line on the page, I added two ValidationSummary controls, one with no ValidationGroup property set, and one with the ValidationGroup property set to DDL.
Running the Validators.aspx page results in the screen shown in Figure 2-11.
Figure 2-11: The Validators.aspx Web Form running
If you click Submit without entering anything, the screen appears as shown in Figure 2-12.
Figure 2-12: The Validators.aspx Web Form after clicking Submit
You should notice a few things about this figure. First, only a single validator has fired, the validator on the first field, TextBox1. Looking at the validators on the page, note that there are only two RequiredFieldValidator controls. Why did the second one not fire? Easy: The RequiredFieldValidator control on the DropDownList1 control belongs to a different validation group.
Next, when the Submit button is clicked and there is no value in the TextBox1 field, the SetFocusOnError property is set to True. This is very convenient, because often you will want the user to immediately correct the problem.
Finally, notice that there is an asterisk (*) next to the TextBox1 field. The longer error message (from the ErrorMessage property) is displayed at the bottom of the form by the ValidationSummary control. The asterisk is from the Text property of the RequiredFieldValidator control.
If you click Validate DropDownList1 Only without adding text to any of the controls and without changing the selection in the drop-down list, the screen appears as shown in Figure 2-13.
Figure 2-13: The Validators.aspx Web Form after clicking Validate DropDownList1 Only
Note that the second validation summary shows the error message related to the drop-down list, the asterisk near the first text box is gone, and an asterisk appears next to the drop-down list, which now has focus. The ability to separately validate sections of the page is a useful new feature of ASP.NET 2.0.
Next, I entered a value (this could be any value) in the TextBox1 field and clicked Submit to clear all error messages. Then I clicked the TextBox1 field and pressed the Tab key. An asterisk immediately appeared next to the text box. Note that the validation summary did not appear, because it appears only when the form is submitted.
I closed the page and made one modification to the ValidationSummary controls, setting the ShowMessageBox property of both to True.
Note | I could have clicked one of the ValidationSummary controls, set its ShowMessageBox property to True in the Properties window, and then repeated the process for the second ValidationSummary control. Instead I clicked one ValidationSummary control in Design view, pressed Shift while clicking the second ValidationSummary control, and set the ShowMessageBox property for both controls in the Properties window at the same time. This feature is really useful when you have a large number of controls for which you want to modify a common property. |
When I re-ran the page and clicked Submit without entering anything, the screen appeared as shown in Figure 2-14.
Figure 2-14: The message showing the validation summary text
You can play with the other controls, entering invalid values to see the error messages. As you work with the validators, you will notice that in most cases you will want to add a RequiredFieldValidator control. Multiple validators can point to the same ControlToValidate property. One last issue: All of the examples in this section on validators have shown client-side validation. When the Submit button was clicked on my browser, the form was not actually submitted to the server. If I used a browser that did not support JavaScript, or if I had JavaScript disabled, the form would have been submitted. To handle this eventuality, you should use code such as the following in any button click event handler.
// Validate the String.Empty ValidationGroup this.Validate(string.Empty); if (this.IsValid!=true) { // Do something... }
The Validate method has an overload that accepts a string parameter to name the validation group. In this case, the button in question validates controls that do not have any validation group set, so I pass in string.Empty, a property of the string class representing an empty string that is, "". I then check the IsValid property of the page, and if it is false, I need to handle it in the area of code with the Do something... comment.