List Controls

List Controls

The list controls family has four members: ListBox, DropDownList, CheckBoxList, and RadioButtonList. All four have two important characteristics in common: they all derive from System.Web.UI.WebControls.ListControl, and they re all designed to present lists of items to the user. ListBox and DropDownList controls display textual items that the user can select. Both render back to the browser as HTML <select> tags. CheckBoxList and RadioButtonList display arrays of check boxes and radio buttons and render as <input type= checkbox > and <input type= radio > tags, respectively. The <input> tags are optionally contained in an HTML table for alignment purposes.

Items in a list control are represented by instances of ListItem. Instances of ListItem are declared with <asp:ListItem> tags. Inside a ListItem are string properties named Text and Value. Text exposes the text that represents the item in a list control; Value allows an arbitrary string to be associated with the item. ListItem also exposes a Boolean property named Selected that determines whether the item is selected. The following statements declare a ListBox control containing four items and select the second item:

<asp:ListBox  RunAt="server"> <asp:ListItem Text="John" RunAt="server" /> <asp:ListItem Text="Paul" Selected="true" RunAt="server" /> <asp:ListItem Text="George" RunAt="server" /> <asp:ListItem Text="Ringo" RunAt="server" /> </asp:ListBox>

A minor change to the code produces a DropDownList instead of a ListBox:

<asp:DropDownList  RunAt="server"> <asp:ListItem Text="John" RunAt="server" /> <asp:ListItem Text="Paul" Selected="true" RunAt="server" /> <asp:ListItem Text="George" RunAt="server" /> <asp:ListItem Text="Ringo" RunAt="server" /> </asp:DropDownList>

In a ListBox or DropDownList, a ListItem s Selected property determines whether the item is selected (true) or not selected (false). In a CheckBoxList or RadioButtonList, the same property determines whether the corresponding control is checked or unchecked.

Following a postback, a server-side script doesn t have to examine every item in a list control to determine which one is currently selected. List controls inherit public properties named SelectedIndex and SelectedItem from the base class ListControl. Thus, a script can determine which radio button in a RadioButtonList is selected by reading its 0-based index:

int index = MyRadioButtonList.SelectedIndex;

SelectedIndex and SelectedItem aren t that interesting for CheckBoxList controls because multiple check boxes in the list might be checked, but they re extremely useful for other types of list controls.

List controls fire SelectedIndexChanged events when the selection changes that is, when a new item is selected in a ListBox or DropDownList or a button is clicked in a CheckBoxList or RadioButtonList. By default, the event doesn t fire until something else on the page causes a postback. However, all list controls inherit an AutoPostBack property from ListControl that you can set to true to fire SelectedIndexChanged events immediately.

DropDownList Controls

DropDownList controls display items in a drop-down list that resembles a Windows combo box. A classic use for DropDownList controls is to display a list of the 50 U.S. states in a form that solicits an address. The following code sample presents such a list and echoes the user s choice to the Web page:

<html> <body> <form runat="server"> <asp:DropDownList  RunAt="server"> <asp:ListItem Text="AL" RunAt="server" /> <asp:ListItem Text="AK" RunAt="server" /> <asp:ListItem Text="AR" RunAt="server" /> . . . <asp:ListItem Text="WI" RunAt="server" /> <asp:ListItem Text="WV" RunAt="server" /> <asp:ListItem Text="WY" RunAt="server" /> </asp:DropDownList> <asp:Button Text="Submit" OnClick="OnSubmit" RunAt="server" /> <br> <asp:Label  RunAt="server" /> </form> </body> </html> <script language="C#" runat="server"> void OnSubmit (Object sender, EventArgs e) { Output.Text = StateList.SelectedItem.Text; } </script>

Figure 6-21 later in the chapter contains a complete listing for a DropDownList control that displays the abbreviations of all 50 U.S. states plus the District of Columbia.

ListBox Controls

ListBox controls are similar to DropDownList controls, but they display their items in a static list rather than in a drop-down list. The following example creates a ListBox control that displays the names of the U.S. states and writes the user s selection to the Web page:

<html> <body> <form runat="server"> <asp:ListBox  Rows="10" RunAt="server"> <asp:ListItem Text="Alabama" RunAt="server" /> <asp:ListItem Text="Alaska" RunAt="server" /> <asp:ListItem Text="Arkansas" RunAt="server" /> . . . <asp:ListItem Text="Wisconsin" RunAt="server" /> <asp:ListItem Text="West Virginia" RunAt="server" /> <asp:ListItem Text="Wyoming" RunAt="server" /> </asp:ListBox> <asp:Button Text="Submit" OnClick="OnSubmit" RunAt="server" /> <br> <asp:Label  RunAt="server" /> </form> </body> </html> <script language="C#" runat="server"> void OnSubmit (Object sender, EventArgs e) { Output.Text = StateList.SelectedItem.Text; } </script>

By default, a ListBox control is sized to display only four items at a time. The Rows attribute in the <asp:ListBox> tag above increases the ListBox height to 10 items.

The only functional difference between a ListBox control and a DropDownList is that the former can be programmed to support multiple selections. A SelectionMode= Multiple attribute in the control tag creates a multiple-selection ListBox:

<asp:ListBox  SelectionMode="Multiple" Rows="10" RunAt="server">

Unfortunately, the ListBox class lacks a public method or property for retrieving the indices of the items selected in a multiple-selection list box. To figure out which items the user selected, you have to iterate through all the list box s items, checking their Selected properties one by one. The following method takes a ListBox reference as an input parameter and returns an array of integers containing the 0-based indices of all selected items:

int[] GetSelectedIndices (ListBox lb) { ArrayList a = new ArrayList (); for (int i=0; i<lb.Items.Count; i++) { if (lb.Items[i].Selected) a.Add (i); } int [] indices = new int[a.Count]; a.CopyTo (indices); return indices; }

With GetSelectedIndices defined this way, the statement

int[] indices = GetSelectedIndices (StateList);

identifies all the items selected in the multiple-selection ListBox named StateList.

CheckBoxList Controls

The CheckBoxList control creates an array of check boxes. The following statements display four vertically stacked check boxes:

<asp:CheckBoxList  RunAt="server"> <asp:ListItem Text="John" RunAt="server" /> <asp:ListItem Text="Paul" RunAt="server" /> <asp:ListItem Text="George" RunAt="server" /> <asp:ListItem Text="Ringo" RunAt="server" /> </asp:CheckBoxList>

To determine whether a given check box is checked, read its Selected property from a server-side script:

// Is the third check box checked? if (MyCheckBoxList.Items[2].Selected) { // The check box is checked else { // The check box is not checked }

Creating an array of check boxes with CheckBoxList is generally preferable to using an array of <asp:CheckBox> tags because CheckBoxList makes it easy to align check boxes in rows and columns and to control the spacing between check boxes. Two properties control the check boxes layout: RepeatColumns and RepeatDirection. The following statements create an array of check boxes divided into four rows and three columns. The first row contains the check boxes whose indices are 0 2, the second row check boxes 3 5, and so on:

<asp:CheckBoxList  RepeatColumns="3" RepeatDirection="Horizontal" RunAt="server"> <asp:ListItem Text="Item 0" RunAt="server" /> <asp:ListItem Text="Item 1" RunAt="server" /> <asp:ListItem Text="Item 2" RunAt="server" /> <asp:ListItem Text="Item 3" RunAt="server" /> <asp:ListItem Text="Item 4" RunAt="server" /> <asp:ListItem Text="Item 5" RunAt="server" /> <asp:ListItem Text="Item 6" RunAt="server" /> <asp:ListItem Text="Item 7" RunAt="server" /> <asp:ListItem Text="Item 8" RunAt="server" /> <asp:ListItem Text="Item 9" RunAt="server" /> <asp:ListItem Text="Item 10" RunAt="server" /> <asp:ListItem Text="Item 11" RunAt="server" /> </asp:CheckBoxList>

Changing RepeatDirection to Vertical modifies the array so that the first column contains check boxes 0 3, the second column contains check boxes 4 7, and the third column contains check boxes 8 11:

<asp:CheckBoxList  RepeatColumns="3" RepeatDirection="Vertical" RunAt="server">

To change the spacing between check boxes, use CheckBoxList s CellPadding and CellSpacing properties. The values that you specify are attached to the <table> tag that the CheckBoxList returns.

RadioButtonList Controls

RadioButtonList simplifies the task of creating groups of radio buttons and finding out which radio button in a group is selected. The statements

<asp:RadioButtonList  RunAt="server"> <asp:ListItem Text="John" Selected="true" RunAt="server" /> <asp:ListItem Text="Paul" RunAt="server" /> <asp:ListItem Text="George" RunAt="server" /> <asp:ListItem Text="Ringo" RunAt="server" /> </asp:RadioButtonList>

create a column of radio buttons and check the first one. A server-side script can use RadioButtonList.SelectedIndex to determine which button the user selected:

int index = MyRadioButtonList.SelectedIndex;

Like CheckBoxList, RadioButtonList features properties named RepeatColumns and RepeatDirection that can be used to align the radio buttons in rows and columns, and properties named CellPadding and CellSpacing that control the spacing between radio buttons. Because radio buttons never appear by themselves (that is, without other radio buttons), and because SelectedIndex makes it so easy to find out which radio button is selected, RadioButtonList all but obviates the need for RadioButton to even exist.

Data Binding with List Controls

Think back for a moment to the currency converter Web form named Converter.aspx presented in Chapter 5. Converter.aspx uses a ListBox to display a list of international currencies. But rather than statically defining the ListBox s contents with <asp:ListItem> tags, Converter.aspx adds items to the ListBox by reading entries from an XML file and calling Add on the ListBox s Items collection. Here s that code again:

DataSet ds = new DataSet (); ds.ReadXml (Server.MapPath ("Rates.xml")); foreach (DataRow row in ds.Tables[0].Rows) Currencies.Items.Add (row["Currency"].ToString ());

Because initializing list controls at run time using the results of database queries or data extracted from XML files is so common, ASP.NET s list controls support a feature called data binding. Rather than initialize the ListBox control by calling ListItemCollection.Add repeatedly, Converter.aspx could have done this:

DataSet ds = new DataSet (); ds.ReadXml (Server.MapPath ("Rates.xml")); Currencies.DataSource = ds; Currencies.DataTextField = "Currency"; Currencies.DataBind ();

This method is simpler and more intuitive. It also makes the code more generic by eliminating direct interactions with the DataSet.

How does data binding work? All list controls inherit from ListControl properties named DataSource, DataTextField, and DataValueField. DataSource identifies a data source. It can be initialized with a reference to any object that implements the FCL s IEnumerable or IListSource interface. IEnumerable is an enumeration interface that allows a control to interact with a data source using a well-defined protocol. IListSource permits objects that don t implement IEnumerable themselves but that have subobjects that implement IList (which derives from IEnumerable) to expose their subobjects IList interfaces. Because DataSet implements IListSource, a list control can enumerate the rows in the DataTable that a DataSet contains. DataTextField connects the Text property of the list control s items to a field in the data source. DataValueField specifies which field, if any, provides the items Value properties. List controls also inherit a method named DataBind from the ListControl base class. DataBind commands the control to initialize itself from the data source.

Literally dozens of FCL classes implement IEnumerable, meaning a list control can bind to a wide variety of data sources. The following example initializes a ListBox named MyListBox by binding to an array of strings. The example works because an array is an instance of System.Array, and System.Array implements IList:

string[] names = { "John", "Paul", "George", "Ringo" }; MyListBox.DataSource = names; MyListBox.DataBind ();

There s no need to initialize DataTextField when binding to an array because an array holds a single column of data. That column is automatically bound to the list items Text property.

You can write custom data types that support binding to list controls by implementing IEnumerable in those types. The following example defines a class named Beatles that serves up the names of the Fab Four. It implements IEnumerable s one and only method, GetEnumerator, by returning an IEnumerator interface implemented by a nested class named Enumerator:

class Beatles : IEnumerable { protected Enumerator enumerator = new Enumerator (); public IEnumerator GetEnumerator () { return enumerator; } public class Enumerator : IEnumerator { protected int index = -1; protected string[] names = { "John", "Paul", "George", "Ringo" }; public object Current { get { if (index == -1) index = 0; // Just in case return names[index]; } } public bool MoveNext () { if (index < (names.Length - 1)) { index++; return true; } return false; } public void Reset () { index = -1; } } }

Two simple statements initialize a ListBox control with the names encapsulated in Beatles:

MyListBox.DataSource = new Beatles (); MyListBox.DataBind ();

Figure 6-1 contains a modified version of Converter.aspx that populates its list box by binding to a DataSet containing the currency and exchange values read from Rates.xml. It also stores exchange rates in the list box items Value properties, eliminating the need to access the XML file again when OnConvert is called. Changes are highlighted in bold.

Converter2.aspx

<%@ Import Namespace=System.Data %> <html> <body> <h1>Currency Converter</h1> <hr> <form runat="server"> Target Currency<br> <asp:ListBox  Width="256" RunAt="server" /><br> <br> Amount in U.S. Dollars<br> <asp:TextBox  Width="256" RunAt="server" /><br> <br> <asp:Button Text="Convert"  Width="256" RunAt="server" /><br> <br> <asp:Label  RunAt="server" /> </form> </body> </html> <script language="C#" runat="server"> void Page_Init (Object sender, EventArgs e) { // Wire the Convert button to OnConvert ConvertButton.Click += new EventHandler (OnConvert); } void Page_Load (Object sender, EventArgs e) { // If this isn't a postback, initialize the ListBox if (!IsPostBack) { DataSet ds = new DataSet (); ds.ReadXml (Server.MapPath ("Rates.xml")); Currencies.DataSource = ds; Currencies.DataTextField = "Currency"; Currencies.DataValueField = "Exchange"; Currencies.DataBind (); Currencies.SelectedIndex = 0; } } void OnConvert (Object sender, EventArgs e) { // Perform the conversion and display the results

 try { decimal dollars = Convert.ToDecimal (USD.Text); decimal rate = Convert.ToDecimal (Currencies.SelectedItem.Value); decimal amount = dollars * rate; Output.Text = amount.ToString ("f2"); } catch (FormatException) { Output.Text = "Error"; } } </script>

Figure 6-1

A currency converter that takes advantage of data binding.



Programming Microsoft  .NET
Applied MicrosoftNET Framework Programming in Microsoft Visual BasicNET
ISBN: B000MUD834
EAN: N/A
Year: 2002
Pages: 101

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net