5.7 Selecting from a ListASP.NET provides four ASP controls for selecting either single or multiple items from a list: All of these controls are derived from ListControl and have much in common:
The ListBox and DropDownList controls differ from the other two list controls (CheckBoxList and RadionButtonList) in that they appear to the user to be a single control (a list box or a drop-down list) rather than a collection of buttons or checkboxes. The ListBox and DropDownList controls lend themselves to longer lists because they scroll. Table 5-5 summarizes the differences among the four list controls.
The following sections describe the controls and objects related to selecting items from a list. 5.7.1 ListItem ObjectThere are four ASP controls that allow you to select from a list, all derived from the ListControl class. A ListControl control consists of a collection of ListItem objects. Each ListItem object has two properties, as Table 5-6 shows.
When dealing with lists, it is very common to display one thing to the user, but to pass the selection to your code as something different. For example, if presenting your users with a list of states, the list might display state names, such as Massachusetts. But when they select an item, the program will pass the selected item as ma. Massachusetts would be the ListItem object's Text property, and ma would be the Value property. The Text property can be specified in one of two ways:
There can be either a closing tag with no inner HTML, or the opening tag can be self-closing. All three of the following lines are equivalent: <asp:ListItem >Item 7</asp:ListItem> <asp:ListItem text="Item 7"></asp:ListItem> <asp:ListItem text="Item 7"/> If both a Text property and inner HTML content are specified, the inner HTML content will be displayed. For example, consider the following line: <asp:ListItem text="Item 7">Item 8</asp:ListItem> If that line were used, then "Item 8" is what would be displayed on the web page. The Value property can be set similarly to the Text property. So, for example, the lines of code presented previously could be modified to also set the value, as follows: <asp:ListItem value="7">Item 7</asp:ListItem> <asp:ListItem text="Item 7" value="7"></asp:ListItem> <asp:ListItem text="Item 7" value="7"/> 5.7.2 CheckBoxList ControlThe CheckBoxList is a parent control containing a collection of CheckBox items. It is very similar to the group of CheckBox controls shown previously in Example 5-10 and Example 5-11, except that all the child checkboxes are handled as a group. The CheckBoxList control derives from ListControl rather than directly from WebControl. The CheckBoxList control is better suited than individual checkboxes for creating a series of checkboxes out of data in a database, although either type of control can be bound to data. Chapter 9 discusses data binding to a database. There are three ways to add items to a CheckBoxList:
5.7.2.1 Adding items staticallyThe web page shown in Example 5-14 demonstrates many of the properties of CheckBoxLists. The list items are added statically in the HTML code. The CheckBoxList control attributes specify the appearance and behavior of the control. (This code is the same for both C# and VB.) Figure 5-7 shows the resulting web page. Example 5-14. CheckBoxLists, ASPCheckBoxList.aspx<html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxLists</h2> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" runat="server"> <asp:ListItem> Item 1 </asp:ListItem> <asp:ListItem> Item 2 </asp:ListItem> <asp:ListItem> Item 3 </asp:ListItem> <asp:ListItem> Item 4 </asp:ListItem> <asp:ListItem> Item 5 </asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> Figure 5-7. CheckBoxList statically added itemsIn the code in Example 5-14, default values were used for those properties that have defaults, as indicated in Table 5-7. By changing the RepeatDirection, RepeatLayout, and TextAlign properties to Horizontal, Flow, and Left, respectively, you get the results shown in Figure 5-8. Figure 5-8. Static CheckBox list modified to use non-default values
5.7.2.2 Adding items programmatically from an arrayThere are times when you do not know at compile time what checkboxes you want to create. For example, you may want to draw the choices from a database. In these cases, you need to be able to add items programmatically. In Example 5-15 (in C#) and Example 5-16 (in VB.NET), ListItem objects are added both programmatically and also are hard-coded within the CheckBoxList tags, for purposes of illustration. Example 5-15. Adding items from an array in C#, csASPCheckBoxListArray.aspx<%@ Page Language="C#" %> <script runat="server"> void cblGenre_Init(Object Source, EventArgs E) { // create an array of items to add string[] Genre = {"SciFi","Novels", "Computers", "History", "Religion"}; int i; for (i = 0; i < Genre.GetLength(0); i++) { this.cblGenre.Items.Add(new ListItem(Genre[i])); } } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" runat="server"> <asp:ListItem> Item 1 </asp:ListItem> <asp:ListItem> Item 2 </asp:ListItem> <asp:ListItem> Item 3 </asp:ListItem> <asp:ListItem> Item 4 </asp:ListItem> <asp:ListItem> Item 5 </asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> Example 5-16. Adding items from an array in VB.NET, vbASPCheckBoxListArray.aspx<%@ Page Language="VB" %> <script runat="server"> Sub cblGenre_Init(ByVal Sender as Object, _ ByVal e as EventArgs) ' create an array of items to add dim Genre( ) as string = {"SciFi", "Novels", "Computers", "History", "Religion"} dim i as integer For i = 0 To Genre.GetLength(0) - 1 cblGenre.Items.Add(new ListItem(Genre(i))) Next End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" runat="server"> <asp:ListItem> Item 1 </asp:ListItem> <asp:ListItem> Item 2 </asp:ListItem> <asp:ListItem> Item 3 </asp:ListItem> <asp:ListItem> Item 4 </asp:ListItem> <asp:ListItem> Item 5 </asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> You add an attribute to the control tag that implements an event handler for control initialization: onInit="cblGenre_Init" Then you add the cblGenre_Init method, called by onInit, to the script block at the beginning of the page. This method creates a string array of genres to add to the list of checkboxes. Then a for loop is used to iterate through the array, calling the Add method on each item to add a new ListItem object to the CheckBoxList control. Notice the slight difference in the logic used in the for loops between the C# code and the VB.NET code. This is because the C# loop repeats while the second parameter is true, while the VB.NET loop repeats until the end value is exceeded. Therefore, in the VB.NET loop you have to subtract 1 from the end value. When you run the web pages in Example 5-15 or Example 5-16, you get the results shown in Figure 5-9. You can modify the code in Example 5-15 and Example 5-16 to add Value properties for some of the ListItems created in the CheckBoxList tag, as well as in all the ListItem objects created in the cblGenre_Init event procedure. Example 5-17 shows the code to do so in C#, and Example 5-18 shows the same code in VB.NET. Code lines that have been added or modified are shown in boldface. Example 5-17. Adding items with values to CheckBoxList from array using C#, csASPCheckBoxListArrayValue.aspx<%@ Page Language="C#" %> <script runat="server"> void cblGenre_Init(Object Source, EventArgs E) { // create arrays of items to add string[] Genre = {"SciFi","Novels", "Computers", "History", "Religion"}; string[] Code = {"sf","nvl", "cmp", "his", "rel"}; int i; for (i = 0; i < Genre.GetLength(0); i++) { // Add both Text and Value this.cblGenre.Items.Add(new ListItem(Genre[i],Code[i])); } } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array With a Value</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" runat="server"> <asp:ListItem value="1"> Item 1 </asp:ListItem> <asp:ListItem text="Item 2" value="2"></asp:ListItem> <asp:ListItem text="Item 3"/> <asp:ListItem text="Item 4"> Inner Item 4 </asp:ListItem> <asp:ListItem value="5"></asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> Example 5-18. Adding items with values to CheckBoxList from array using VB.NET, vbASPCheckBoxListArrayValue.aspx<%@ Page Language="VB" %> <script runat="server"> Sub cblGenre_Init(ByVal Sender as Object, _ ByVal e as EventArgs) ' create arrays of items to add dim Genre( ) as string = {"SciFi", "Novels", "Computers", "History", "Religion"} dim Code( ) as string = {"sf","nvl", "cmp", "his", "rel"} dim i as integer For i = 0 To Genre.GetLength(0) - 1 ' Add both Text and Value cblGenre.Items.Add(new ListItem(Genre(i),Code(i))) Next End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array With a Value</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" runat="server"> <asp:ListItem value="1"> Item 1 </asp:ListItem> <asp:ListItem text="Item 2" value="2"></asp:ListItem> <asp:ListItem text="Item 3"/> <asp:ListItem text="Item 4"> Inner Item 4 </asp:ListItem> <asp:ListItem value="5"></asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> If the code in Example 5-17 or Example 5-18 is run, it will look as shown in Figure 5-10. Figure 5-9. CheckBoxList with items added from an arrayFigure 5-10. CheckBoxList with items and values added from an arrayIn cblGenre_Init, where you previously created a single string array to hold the Text properties, there are now two string arrays: one for the Text properties and one for the Value properties. You now use the overloaded Add method that takes two arguments. The first argument is the Text property, and the second argument is the Value property. In C#, this looks like: this.cblGenre.Items.Add(new ListItem(Genre[i],Code[i])); In VB.NET, it looks like: cblGenre.Items.Add(new ListItem(Genre(i),Code(i))) Finally, in creating the static ListItems, you used several different methods of creating Values and Text, including instances of missing Text (Item 5), missing Value (Item 3, Item 4, Item 6), and divergent Text property from inner HTML content (Item 4). The differences between Figure 5-9 and Figure 5-11 can be seen in Items 4 and 5. You can see that if the Value is missing, then the Text is displayed. If the Text is missing, then the Value is displayed. If the Text is different from the inner HTML content, then the inner HTML content is displayed. 5.7.2.3 Adding items from a data sourceThe real power of adding items programmatically comes when you can use a data source to populate the items in a CheckBoxList control. The ultimate data source, obviously, is a database. This will be covered in Chapter 9. However, you can use the array just created to demonstrate binding to a data source. By replacing the for loop in cblGenre_Init in Example 5-15 and Example 5-16 with two lines (which specify the data source and then bind to it), the method now appears as shown in Example 5-19 for C# and Example 5-20 for VB .NET. (Note that the lines of code that have been added to the two event procedures—shown in bold—are identical in the C# and VB .NET versions of the program, except for the trailing semicolon in C#.) Example 5-19. Adding items to a CheckBoxList from a data source using C#, csASPCheckBoxListDataBind.aspx<%@ Page Language="C#" %> <script runat="server"> void cblGenre_Init(Object Source, EventArgs E) { // create an array of items to add string[] Genre = {"SciFi","Novels", "Computers", "History", "Religion"}; cblGenre.DataSource = Genre; cblGenre.DataBind( ); } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array Using DataBinding</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" runat="server"> <asp:ListItem> Item 1 </asp:ListItem> <asp:ListItem> Item 2 </asp:ListItem> <asp:ListItem> Item 3 </asp:ListItem> <asp:ListItem> Item 4 </asp:ListItem> <asp:ListItem> Item 5 </asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> </form> </body> </html> Example 5-20. Adding items to a CheckBoxList from a data source using VB.NET, vbASPCheckBoxListDataBind.aspx<%@ Page Language="VB" %>
<script runat="server">
Sub cblGenre_Init(ByVal Sender as Object, _
ByVal e as EventArgs)
' create an array of items to add
dim Genre( ) as string = {"SciFi", "Novels", "Computers", "History", "Religion"}
cblGenre.DataSource = Genre
cblGenre.DataBind( )
End Sub
</script>
<html>
<body>
<form runat="server">
<h1>ASP Controls</h1>
<h2>CheckBoxList</h2>
<h3>Adding Items From An Array Using DataBinding</h3>
<asp:CheckBoxList
id="cblGenre"
autoPostBack="true"
cellPadding="5"
cellSpacing="10"
repeatColumns="3"
repeatDirection="vertical"
RepeatLayout="table"
textAlign="right"
onInit="cblGenre_Init"
runat="server">
<asp:ListItem> Item 1 </asp:ListItem>
<asp:ListItem> Item 2 </asp:ListItem>
<asp:ListItem> Item 3 </asp:ListItem>
<asp:ListItem> Item 4 </asp:ListItem>
<asp:ListItem> Item 5 </asp:ListItem>
<asp:ListItem> Item 6 </asp:ListItem>
</asp:CheckBoxList>
</form>
</body>
</html>
You might expect the results to be unchanged from Figure 5-10, but that is not the case. Instead you get the results shown in Figure 5-11. Figure 5-11. CheckBoxList with items added using DataBindingIn the previous example, using the for loop, ListItems were added by the Init method after the control was created. In this example, the pre-existing ListItem objects were replaced by the new data source. This is because the ListControl.Items collection is initialized by the data source, so any ListItem objects previously defined are lost. 5.7.2.4 Responding to user selectionsWhen a user checks or unchecks one of the checkboxes in a CheckBoxList, the SelectedIndexChanged event is raised. This event passes an argument of type EventArgs, which does not expose any properties. By setting an attribute for handling this event and putting code in the event handler method, you can respond to the user clicking on one of the checkboxes. If AutoPostBack is set to true, the response occurs immediately. Otherwise, the response occurs the next time the form is posted to the server. The additional code added to the previous examples, shown highlighted in Example 5-21 for C# and Example 5-22 for VB.NET, demonstrates responding to SelectedIndexChanged. Example 5-21. Responding to CheckBoxList User Action using C#, csASPCheckBoxListEvents.aspx<%@ Page Language="C#" %> <script runat="server"> void cblGenre_Init(Object Source, EventArgs E) { // create arrays of items to add string[] Genre = {"SciFi","Novels", "Computers", "History", "Religion"}; string[] Code = {"sf","nvl", "cmp", "his", "rel"}; int i; for (i = 0; i < Genre.GetLength(0); i++) { // Add both Text and Value this.cblGenre.Items.Add(new ListItem(Genre[i],Code[i])); } } void cblGenre_SelectedIndexChanged(Object Source, EventArgs E) { StringBuilder sb = new StringBuilder( ); foreach(ListItem li in cblGenre.Items) { if (li.Selected == true) { sb.Append("<br/>" + li.Value + " - " + li.Text); } } if (sb.Length == 0) lblGenre.Text = "No genres selected."; else lblGenre.Text = sb.ToString( ); } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Responding to Events</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" onSelectedIndexChanged="cblGenre_SelectedIndexChanged" runat="server"> <asp:ListItem value="1"> Item 1 </asp:ListItem> <asp:ListItem text="Item 2" value="2"></asp:ListItem> <asp:ListItem text="Item 3"/> <asp:ListItem text="Item 4"> Inner Item 4 </asp:ListItem> <asp:ListItem value="5"></asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> <asp:label id="lblGenre" runat="server" /> </form> </body> </html> Example 5-22. Responding to CheckBoxList User Action using VB.NET- vbASPCheckBoxListEvents.aspx<%@ Page Language="VB" %> <script runat="server"> Sub cblGenre_Init(ByVal Sender as Object, _ ByVal e as EventArgs) ' create arrays of items to add dim Genre( ) as string = {"SciFi", "Novels", "Computers", "History", "Religion"} dim Code( ) as string = {"sf","nvl", "cmp", "his", "rel"} dim i as integer For i = 0 To Genre.GetLength(0) - 1 ' Add both Text and Value cblGenre.Items.Add(new ListItem(Genre(i),Code(i))) Next End Sub Sub cblGenre_SelectedIndexChanged(ByVal Sender as Object, _ ByVal e as EventArgs) dim sb as new StringBuilder( ) dim li as ListItem for each li in cblGenre.Items if li.Selected then sb.Append("<br/>" & li.Value & " - " & li.Text) end if next li if sb.Length = 0 then lblGenre.Text = "No genres selected." else lblGenre.Text = sb.ToString( ) end if End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>CheckBoxList</h2> <h3>Adding Items From An Array With a Value</h3> <asp:CheckBoxList id="cblGenre" autoPostBack="true" cellPadding="5" cellSpacing="10" repeatColumns="3" repeatDirection="vertical" RepeatLayout="table" textAlign="right" onInit="cblGenre_Init" onSelectedIndexChanged="cblGenre_SelectedIndexChanged" runat="server"> <asp:ListItem value="1"> Item 1 </asp:ListItem> <asp:ListItem text="Item 2" value="2"></asp:ListItem> <asp:ListItem text="Item 3"/> <asp:ListItem text="Item 4"> Inner Item 4 </asp:ListItem> <asp:ListItem value="5"></asp:ListItem> <asp:ListItem> Item 6 </asp:ListItem> </asp:CheckBoxList> <asp:label id="lblGenre" runat="server" /> </form> </body> </html>
In the code in Example 5-21 and Example 5-22, you add an attribute named OnSelectedIndexChanged to identify the event handler for the SelectedIndexChanged event. Like all event handlers, the name comes from prepending the word "On" to the event name. You also add a Label control to the form, lblGenre, to display the selected items. The event handler points to a method in the script block at the top of the page called cblGenre_SelectedIndexChanged. In this event handler, you iterate through the collection of ListItems in the CheckBoxList. For each ListItem, you check to see if the Selected property is true. If it is, then you add the Value property of that item to the HTML string you are constructing, using the StringBuilder class. Finally, the length of the StringBuilder string is tested. If it is zero length, then an appropriate message is displayed, otherwise the StringBuilder string containing the selected values is displayed. The results of Example 5-21 and Example 5-22 are shown in Figure 5-12, where several items have been selected. Figure 5-12. Responding to CheckBoxList user selections5.7.3 RadioButtonList ControlThe RadioButtonList control is very similar to the CheckBoxList control. They are both derived from the ListControl class and share all of the same properties, events, and methods. The only difference between the two is that the RadioButtonList control can have only one item selected at a time. When an item is selected, any other selected item is deselected. The RadioButtonList and the CheckBoxList controls share the two properties inherited from ListControl that are shown in Table 5-8.
To demonstrate how these are used, modify the code in Example 5-12 and Example 5-13, replacing the three radio buttons controlling the font size in grpSize with a single RadioButtonList, calling it rblSize. Example 5-23 shows the resulting C# ASP.NET page, while Example 5-24 shows the ASP.NET page with VB.NET code. Example 5-23. RadioButtonList control using C#, csASPRadioButtonList.aspx<%@ Page Language="C#" %> <script runat="server"> void lblTime_Init(Object Source, EventArgs E) { lblTime.Font.Name = "Verdana"; lblTime.Font.Size = 20; lblTime.Font.Bold = true; lblTime.Font.Italic = true; lblTime.Text = DateTime.Now.ToString( ); } void rblSize_SelectedIndexChanged(Object Source, EventArgs E) { // Check to verify that something has been selected. if (rblSize.SelectedIndex != -1) { int size = Convert.ToInt32(rblSize.SelectedItem.Value); lblTime.Font.Size = size; } } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>RadioButtonList</h2> <asp:label id="lblTime" runat="server" onInit="lblTime_Init"/> <asp:radioButtonList id="rblSize" autoPostBack="true" cellSpacing="20" repeatColumns="3" repeatDirection="horizontal" RepeatLayout="table" textAlign="right" onSelectedIndexChanged="rblSize_SelectedIndexChanged" runat="server"> <asp:ListItem text="10pt" value="10"/> <asp:ListItem text="14pt" value="14"/> <asp:ListItem text="16pt" value="16"/> </asp:radioButtonList> </form> </body> </html> Example 5-24. RadioButtonList control using VB.NET, vbASPRadioButtonList.aspx<%@ Page Language="VB" %> <script runat="server"> Sub lblTime_Init(ByVal Sender as Object, _ ByVal e as EventArgs) lblTime.Font.Name = "Verdana" lblTime.Font.Size = new FontUnit(20) lblTime.Font.Bold = true lblTime.Font.Italic = true lblTime.Text = DateTime.Now( ) End Sub Sub rblSize_SelectedIndexChanged(ByVal Sender as Object, _ ByVal e as EventArgs) ' Check to verify that something has been selected. if (rblSize.SelectedIndex <> -1) then dim size as integer = Convert.ToInt32(rblSize.SelectedItem.Value) lblTime.Font.Size = new FontUnit(size) end if End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>RadioButtonList</h2> <asp:label id="lblTime" runat="server" onInit="lblTime_Init"/> <asp:radioButtonList id="rblSize" autoPostBack="true" cellSpacing="20" repeatColumns="3" repeatDirection="horizontal" RepeatLayout="table" textAlign="right" onSelectedIndexChanged="rblSize_SelectedIndexChanged" runat="server"> <asp:ListItem text="10pt" value="10"/> <asp:ListItem text="14pt" value="14"/> <asp:ListItem text="16pt" value="16"/> </asp:radioButtonList> </form> </body> </html> The results of Example 5-23 or Example 5-24 are shown in Figure 5-13. It doesn't look much different than the individual radio buttons, but it is much easier to populate from a data source. Figure 5-13. Using the RadioButtonList controlIn Example 5-23 and Example 5-24, the original separate radio buttons are replaced by a RadioButtonList control. Note that each ListItem object has both a Text property and a Value property. The event handler, rblSize_SelectedIndexChanged, takes an integer value for the Font.Size property in the C# code: int size = Convert.ToInt32(rblSize.SelectedItem.Value); lblTime.Font.Size = size; but requires a FontUnit type in VB.NET: dim size as integer = Convert.ToInt32(rblSize.SelectedItem.Value) lblTime.Font.Size = new FontUnit(size) As described previously, in conjunction with Table 5-1, this is because C# provides an implicit conversion operator, but VB.NET does not. The event handler method makes use of the SelectedIndex and SelectedItem properties mentioned previously. The SelectedIndex property represents the lowest integer value index of all the selected items. The SelectedItem property returns the Text property of the item pointed to by SelectedIndex. Since a RadioButtonList, by definition, can have at most a single selected item, then SelectedIndex and SelectedItem will tell us which item is selected. These properties of a CheckBoxList control or other ListControl control (which allow multi-selection) are more ambiguous. Example 5-23 and Example 5-24 verify that at least one of the values has been selected. If no item has been selected, then the SelectedIndex property is equal to -1. If an item has been selected, you set the Font.Size property by converting the SelectedItem.Value property to an integer in C# and by passing the SelectedItem.Value as an argument to the FontUnit class constructor in VB.NET. Note that the following two lines of C# code in Example 5-23: int size = Convert.ToInt32(rblSize.SelectedItem.Value); lblTime.Font.Size = size; could just as easily have been written as a single line: lblTime.Font.Size = Convert.ToInt32(rblSize.SelectedItem.Value); (However, I often use the more verbose version to enhance readability and make the code easier to debug.) 5.7.4 DropDownList ControlDropDownList controls display a single item at a time with a button for dropping the list to display more selections. Only a single item can be selected. The code in Example 5-25 demonstrates a DropDownList control in C#, while the code in Example 5-26 shows the same in VB.NET. A two-dimensional string array is used to hold both the Text and Value properties. The array is then used to add the ListItem objects. Example 5-25. DropDownList control using C#, csASPDropDownList.aspx<%@ Page Language="C#" %> <script runat="server"> void Page_Load(Object sender, EventArgs e) { if (! IsPostBack) { // Build 2 dimensional array for the lists // First dimension contains bookname // 2nd dimension contains ISBN number string[,] books = { {"Programming C#","0596001177"}, {"Programming ASP.NET","0596001711"}, {"WebClasses From Scratch","0789721260"}, {"Teach Yourself C++ in 21 Days","067232072X"}, {"Teach Yourself C++ in 10 Minutes","067231603X"}, {"XML & Java From Scratch","0789724766"}, {"Complete Idiot's Guide to a Career in Computer Programming", {"XML Web Documents From Scratch","0789723166"}, {"Clouds To Code","1861000952"}, {"C++: An Introduction to Programming","1575760614"}, {"C++ Unleashed","0672312395"} }; // Now populate the list. int i; for (i = 0; i < books.GetLength(0); i++) { // Add both Text and Value ddl.Items.Add(new ListItem(books[i,0],books[i,1])); } } } void ddl_SelectedIndexChanged(Object Source, EventArgs E) { // Check to verify that something has been selected. if (ddl.SelectedIndex != -1) { lblDdl.Text=ddl.SelectedItem.Text + " ---> ISBN: " + ddl.SelectedItem.Value; } } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>DropDownList</h2> <asp:dropDownList id="ddl" autoPostBack="true" onSelectedIndexChanged="ddl_SelectedIndexChanged" runat="server"/> <br/> <asp:label id="lblDdl" runat="server" /> </form> </body> </html> Example 5-26. DropDownList control using VB.NET, vbASPDropDownList.aspx<%@ Page Language="VB" %> <script runat="server"> Sub Page_Load(ByVal Sender as Object, _ ByVal e as EventArgs) if not IsPostBack then ' Build 2 dimensional array for the lists ' First dimension contains bookname ' 2nd dimension contains ISBN number dim books(,) as string = { _ {"Programming C#","0596001177"}, _ {"Programming ASP.NET","1234567890"}, _ {"WebClasses From Scratch","0789721260"}, _ {"Teach Yourself C++ in 21 Days","067232072X"}, _ {"Teach Yourself C++ in 10 Minutes","067231603X"}, _ {"XML & Java From Scratch","0789724766"}, _ {"Complete Idiot's Guide to a Career in Computer Programming", _ "0789719959"}, _ {"XML Web Documents From Scratch","0789723166"}, _ {"Clouds To Code","1861000952"}, _ {"C++: An Introduction to Programming","1575760614"}, _ {"C++ Unleashed","0672312395"} _ } ' Now populate the list. dim i as integer for i = 0 to books.GetLength(0) - 1 ' Add both Text and Value ddl.Items.Add(new ListItem(books(i,0),books(i,1))) next end if End Sub Sub ddl_SelectedIndexChanged(ByVal Sender as Object, _ ByVal e as EventArgs) ' Check to verify that something has been selected. if ddl.SelectedIndex <> -1 then lblDdl.Text=ddl.SelectedItem.Text & " ---> ISBN: " & _ ddl.SelectedItem.Value end if End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>DropDownList</h2> <asp:dropDownList id="ddl" autoPostBack="true" onSelectedIndexChanged="ddl_SelectedIndexChanged" runat="server"/> <br/> <asp:label id="lblDdl" runat="server" /> </form> </body> </html> The results of Example 5-25 or Example 5-26 are shown in Figure 5-14. Figure 5-14. DropDownList controlIn Example 5-25 and Example 5-26, a DropDownList with the id of ddl is added. This control is populated when the page is first loaded, in the Page_Load event handler method. To prevent this code running every time the page is reloaded, you test to see if the IsPostBack property is true. The IsPostBack property is false when the page is first loaded, but is set to true whenever the form is posted back to the server as a result of user action on one of the controls. In many applications, the contents of controls are filled from a database, which is a relatively expensive operation. Only hitting the database when necessary makes the implementation more efficient. In Example 5-23 and Example 5-24, you used two arrays to populate a CheckBoxList with both the Text and Value properties. In Example 5-25 and Example 5-26, you use a single two-dimensional array to accomplish the same thing. As before, you call the Items.Add method to add the ListItems to the control. In Chapter 9, you will see how to populate a ListControl from a database. As with the other ListControls, the OnSelectedIndexChanged attribute points to the event handler method, ddl_SelectedIndexChanged. In that method, just as with the RadioButtonList control, you first check to see if something is selected by testing if the SelectedIndex property is not equal to -1. If an item has been selected, you display a concatenation of SelectedItem.Text and SelectedItem.Value in the Label called lblDdl. 5.7.5 ListBox ControlListBox controls are very similar to DropDownList controls. Example 5-27 and Example 5-28 demonstrate two different ListBoxes: one using single selection and one allowing multiple selection. As you will see, they are almost identical in implementation, with the only significant difference being the method used to identify the selected item(s). The code in Example 5-27 and Example 5-28 for implementing ListBox controls is nearly identical to that in Example 5-25 and Example 5-26 for implementing DropDownLists. The differences, highlighted in Example 5-27 and Example 5-28, include the addition of the two DropDownList controls, modification to the Page_Load method to populate those controls, and the addition of event handlers for those two controls. Example 5-27. ListBox control using C#, csASPListBox.aspx<%@ Page Language="C#" %> <script runat="server"> void Page_Load(Object sender, EventArgs e) { if (! IsPostBack) { // Build 2 dimensional array for the lists // First dimension contains bookname // 2nd dimension contains ISBN number string[,] books = { {"Programming C#","0596001177"}, {"Programming ASP.NET","0596001711"}, {"WebClasses From Scratch","0789721260"}, {"Teach Yourself C++ in 21 Days","067232072X"}, {"Teach Yourself C++ in 10 Minutes","067231603X"}, {"XML & Java From Scratch","0789724766"}, {"Complete Idiot's Guide to a Career in Computer Programming", {"XML Web Documents From Scratch","0789723166"}, {"Clouds To Code","1861000952"}, {"C++: An Introduction to Programming","1575760614"}, {"C++ Unleashed","0672312395"} }; // Now populate the lists. int i; for (i = 0; i < books.GetLength(0); i++) { // Add both Text and Value lbSingle.Items.Add(new ListItem(books[i,0],books[i,1])); lbMulti.Items.Add(new ListItem(books[i,0],books[i,1])); } } } void lbSingle_SelectedIndexChanged(Object Source, EventArgs E) { // Check to verify that something has been selected. if (lbSingle.SelectedIndex != -1) { lblLbSingle.Text=lbSingle.SelectedItem.Text + " ---> ISBN: " + lbSingle.SelectedItem.Value; } } void lbMulti_SelectedIndexChanged(Object Source, EventArgs E) { string str = ""; foreach(ListItem li in lbMulti.Items) { if (li.Selected == true) { str += "<br/>" + li.Text + " ---> ISBN: " +li.Value; } } if (str.Length == 0) lblLbMulti.Text = "No books selected."; else lblLbMulti.Text = str; } </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>ListBox</h2> <h3>ListBox - single selection</h3> <asp:ListBox id="lbSingle" autoPostBack="true" rows="6" selectionMode="single" onSelectedIndexChanged="lbSingle_SelectedIndexChanged" runat="server"/> <br/> <asp:label id="lblLbSingle" runat="server" /> <br/> <h3>ListBox - multiple selection</h3> <asp:ListBox id="lbMulti" autoPostBack="true" selectionMode="multiple" onSelectedIndexChanged="lbMulti_SelectedIndexChanged" runat="server"/> <asp:label id="lblLbMulti" runat="server" /> </form> </body> </html> Example 5-28. ListBox control using VB.NET, vbASPListBox.aspx<%@ Page Language="VB" %> <script runat="server"> Sub Page_Load(ByVal Sender as Object, _ ByVal e as EventArgs) if not IsPostBack then ' Build 2 dimensional array for the lists ' First dimension contains bookname ' 2nd dimension contains ISBN number dim books(,) as string = { _ {"Programming C#","0596001177"}, _ {"Programming ASP.NET","1234567890"}, _ {"WebClasses From Scratch","0789721260"}, _ {"Teach Yourself C++ in 21 Days","067232072X"}, _ {"Teach Yourself C++ in 10 Minutes","067231603X"}, _ {"XML & Java From Scratch","0789724766"}, _ {"Complete Idiot's Guide to a Career in Computer Programming", _ "0789719959"}, _ {"XML Web Documents From Scratch","0789723166"}, _ {"Clouds To Code","1861000952"}, _ {"C++: An Introduction to Programming","1575760614"}, _ {"C++ Unleashed","0672312395"} _ } ' Now populate the lists. dim i as integer for i = 0 to books.GetLength(0) - 1 ' Add both Text and Value lbSingle.Items.Add(new ListItem(books(i,0),books(i,1))) lbMulti.Items.Add(new ListItem(books(i,0),books(i,1))) next end if End Sub Sub lbSingle_SelectedIndexChanged(ByVal Sender as Object, _ ByVal e as EventArgs) ' Check to verify that something has been selected. if lbSingle.SelectedIndex <> -1 then lblLbSingle.Text=lbSingle.SelectedItem.Text & " ---> ISBN: " & _ lbSingle.SelectedItem.Value end if End Sub Sub lbMulti_SelectedIndexChanged(ByVal Sender as Object, _ ByVal e as EventArgs) dim sb as new StringBuilder( ) dim li as ListItem for each li in lbMulti.Items if li.Selected then sb.Append("<br/>" & li.Text & " ---> ISBN: " & li.Value) end if next li if sb.Length = 0 then lblLbMulti.Text = "No books selected." else lblLbMulti.Text = sb.ToString( ) end if End Sub </script> <html> <body> <form runat="server"> <h1>ASP Controls</h1> <h2>ListBox</h2> <h3>ListBox - single selection</h3> <asp:ListBox id="lbSingle" autoPostBack="true" rows="6" selectionMode="single" onSelectedIndexChanged="lbSingle_SelectedIndexChanged" runat="server"/> <br/> <asp:label id="lblLbSingle" runat="server" /> <br/> <h3>ListBox - multiple selection</h3> <asp:ListBox id="lbMulti" autoPostBack="true" selectionMode="multiple" onSelectedIndexChanged="lbMulti_SelectedIndexChanged" runat="server"/> <asp:label id="lblLbMulti" runat="server" /> </form> </body> </html> ListBox controls have two properties in addition to those inherited from ListControl. These properties are shown in Table 5-9.
The first ListBox added in Example 5-27 and Example 5-28, with an id of lbSingle, is a single selection list box. The Rows property has been set to 6, and 6 items are displayed. Since the control has been populated with more than 6 items, a vertical scrollbar automatically appears. If a second item is selected, the first item is deselected. As with most of the examples in this chapter, AutoPostBack has been set to true so that the effects of the change are visible immediately. The second ListBox control, with an id of lbMulti, is a multiple selection list box. The Rows property has not been set, so the default 4 rows are visible. Since it is multiselect, the standard Windows techniques of multiselection can be used.
The event handlers for processing the selections of the two list boxes are very different. The event handler for the single selection list box is very similar to the one for the DropDownList control or any other single select ListControl, such as the RadioButtonList control. The event handler for the multiselect list box, on the other hand, is more like that used for the CheckBoxList control. It iterates through the collection of ListItem objects, checking each to see if the Selected property is true. If it is true, then the Text and Value properties are added to the string for output to a label. The result of running the web page in Example 5-27 or Example 5-28 is shown in Figure 5-15. Figure 5-15. ListBox controls |