Scott on Writing

Musings on technical writing...

Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem

I was recently helping a colleague squash a bug that had popped up on a page that involved a DropDownList. Specifically, an HttpException was being thrown with the error message Cannot have multiple items selected in a DropDownList. This exception is raised, as the message notes, if a DropDownList contains multiple ListItems whose Selected properties are set to true.

The page in question had a DropDownList whose values were populated from a web service on the first page load. Shortly after this population code was a foreach loop that looped through the items in the DropDownList looking for a ListItem whose value matched a user-specific setting. The first such ListItem found had its Selected property set to true before exiting the loop. The code (in the Page_Load event handler) looked something like this:

if (!Page.IsPostBack)
{
    ... Populate MyDropDownList ...
 
    ... More Code ...
 
    foreach(ListItem li in MyDropDownList.Items)
        if (li.Value.StartsWith("some value specific to the user visiting the page"))
        {
            li.Selected = true;
            break;
        }
}

This error was perplexing because while there was some code that occurred between the population of the DropDownList, when the appropriate ListItem was selected, and when the page was rendered, none of that code set the Selected property to true or assigned a value to the DropDownList's SelectedIndex or SelectedValue properties. To unearth the cause of this error I fired up the debugger and set a breakpoint at the point where the DropDownList was populated. I then put the following statements in the Watch window:

  • MyDropDownList.Items[0].Selected
  • MyDropDownList.Items[1].Selected
  • MyDropDownList.Items[2].Selected
  • ...

I wanted to see what items became selected and when. As I was stepping through the code, things started to unfold as I expected. After the DropDownList was populated all of the Items[i].Selected values returned false. But then in the code between where the DropDownList was populated and when a ListItem was selected based on the user's settings, there was a call to a method further down in the code-behind class. That method did not set the DropDownList's SelectedIndex or SelectedValue properties so I stepped over it thinking that it couldn't be the cause of my problems. But as I stepped over the method call the MyDropDownList.Items[0].Selected value in the DropDownList changed to true!

I went to look at the code in that method I had just stepped over. This method was (among other things) showing or hiding a Panel on the page based on whether the first DropDownList item was selected. It had code like:

if (MyDropDownList.SelectedIndex == 0)
    SomePanel.Visible = true;
else
    SomePanel.Visible = false;

But here's the rub - merely reading the value of the DropDownList's SelectedIndex property (or SelectedValue) causes the first ListItem in the DropDownList to be selected! This kind of makes sense, I guess. Unlike a ListBox there's always an item in the DropDownList that is selected. What's confusing is that the MyDropDownList.Items[0].Selected property is not true when the data is first bound to the DropDownList, but only after the SelectedIndex or SelectedValue properties are accessed. If these properties had not been read in the method that was called then my code in the Page_Load event handler would have worked as expected and without error.

You can see how the first DropDownList item gets auto-selected when the SelectedIndex property is accessed by examining the SelectedIndex property code using Reflector:

    1 public override int SelectedIndex
    2 {
    3     get
    4     {
    5         int selectedIndex = base.SelectedIndex;
    6         if ((selectedIndex < 0) && (this.Items.Count > 0))
    7         {
    8             this.Items[0].Selected = true;
    9             selectedIndex = 0;
   10         }
   11         return selectedIndex;
   12     }
   13     set
   14     {
   15         base.SelectedIndex = value;
   16     }
   17 }

Note lines 6-10. If the selected index is not set and if there are one or more items in the DropDownList then the first item is automatically selected (line 8)! In short, the first item of the DropDownList was being silently selected between the time the DropDownList was populated and the foreach loop that set the Selected property of some other ListItem based on the user's settings. Hence the resulting Cannot have multiple items selected in a DropDownList exception during rendering of the DropDownList. (Because the DropDownList's SelectedValue property reads the SelectedIndex property, accessing the SelectedValue property also has the side-effect of selecting the first DropDownList item.)

I fixed this by adding a loop that enumerates the DropDownList Items collection just before the foreach loop, setting each ListItem's Selected property to false.

if (!Page.IsPostBack)
{
    ... Populate MyDropDownList ...
 
    ... More Code ...
 
    foreach(ListItem li in MyDropDownList.Items)
        li.Selected = false;
        
    foreach(ListItem li in MyDropDownList.Items)
        if (li.Value.StartsWith("some value specific to the user visiting the page"))
        {
            li.Selected = true;
            break;
        }
}

posted on Friday, February 06, 2009 10:04 AM

Feedback

# re: Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/6/2009 10:36 AM Kevin Steffer

instead of looping through all the Items 2 times just make a call to

MyDropDownList.ClearSelection();

will do the trick for you.

# re: Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/6/2009 12:17 PM Steve

I usually set selectedIndex = -1 before setting some default value

# re: Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/6/2009 7:23 PM lakshminarayanan

Yes Kevin is correct
I had the same problem yesterday and was able to fix by using the ClearSelection()

# Link Listing - February 6, 2009 2/7/2009 5:03 AM Christopher Steen

Link Listing - February 6, 2009

# Scott on Writing - Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/7/2009 12:16 PM DotNetShoutout

Thank you for submitting this cool story - Trackback from DotNetShoutout

# re: Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/8/2009 4:56 PM Chandan

+1 Kevin - easiest, cleanest way to do it.

# Dew Drop - Weekend Edition - February 7-8, 2009 | Alvin Ashcraft's Morning Dew 2/8/2009 5:18 PM Pingback/TrackBack

Dew Drop - Weekend Edition - February 7-8, 2009 | Alvin Ashcraft's Morning Dew

# re: Accessing the DropDownList Control's SelectedIndex or SelectedValue Properties Selects the First ListItem 2/25/2009 10:07 PM Ratish Shriyan

Hi Scott,

I have encountered this error quite a few times,
I found out that when trying to select a list item, setting the selected index would work. Here's what I do,

ddlStateCode.SelectedIndex = ddlStateCode.Items.IndexOf(ddlStateCode.Items.FindByText(value));

and then wrap the above code in a property.
Anyways thanks for the explanation, your website is very much informative.

Cheers!

# linkfeedr &raquo; Blog Archive &raquo; Accessing the DropDownList Control&#8217;s SelectedIndex or SelectedValue Properties Selects the First ListItem - RSS Indexer (beta) 4/17/2009 9:41 PM Pingback/TrackBack

linkfeedr &raquo; Blog Archive &raquo; Accessing the DropDownList Control&#8217;s SelectedIndex or SelectedValue Properties Selects the First ListItem - RSS Indexer (beta)

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<March 2010>
SMTWTFS
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Comment Stats

DayTotal% of Total
Sunday 2056.8%
Monday 42514.1%
Tuesday 51917.2%
Wednesday 55618.4%
Thursday 58019.2%
Friday 54718.1%
Saturday 1886.2%
Total 3020100.0%

Hour1Total% of Total
12:00 AM 782.6%
1:00 AM 812.7%
2:00 AM 682.3%
3:00 AM 822.7%
4:00 AM 692.3%
5:00 AM 1264.2%
6:00 AM 1193.9%
7:00 AM 1816.0%
8:00 AM 1926.4%
9:00 AM 1585.2%
10:00 AM 1886.2%
11:00 AM 1936.4%
12:00 PM 2016.7%
1:00 PM 1846.1%
2:00 PM 1695.6%
3:00 PM 1354.5%
4:00 PM 1153.8%
5:00 PM 1073.5%
6:00 PM 1013.3%
7:00 PM 1073.5%
8:00 PM 923.0%
9:00 PM 882.9%
10:00 PM 913.0%
11:00 PM 953.1%
Total 3020100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.00160
Monday 4.80384
Tuesday 4.04477
Wednesday 7.39680
Thursday 6.26676
Friday 5.07466
Saturday 4.78177
Total 5.403020

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 3.8550
8:00 AM 3.72134
9:00 AM 6.06297
10:00 AM 5.63276
11:00 AM 4.22194
12:00 PM 6.16351
1:00 PM 3.09133
2:00 PM 4.89230
3:00 PM 7.67322
4:00 PM 4.00108
5:00 PM 6.07170
6:00 PM 4.64116
7:00 PM 8.95188
8:00 PM 8.63164
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.403020

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles