tags:

views:

5043

answers:

6

I have a asp.net 2.0 web site with numerous asp:DropDownList controls. The DropDownList control contains the standard info city, state, county etc... info. In addition to the standard codes the site also has custom codes that the users can configure themselves. For example a animal dropdown may contain the values Dog, Cat, Fish, ect...

I am popluating the DropDownList from a SQL 2005 table that I created e.g. tblCodes

Everything works great and users are able to add orders using the numerous DropDownList controls to choose items from the list.

The problem occurrs if a user wants to change one of their custom dropdowns. For example a user would like to change the verbage on a animal type control from Dog to K9. This is where the problem starts.

For all new orders the drop down works fine. When the user retrieved an old order I get the following error in the C# codebehind "'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items."

What's happening is the old order has a database field value of Dog and the DropDownList no longer has Dog in its list since the user changed it to K9.

Any ideas on a workaround?
Is there a way to make the asp:DropDownList accept items not seeded in its list? Is there another control I could use?

+3  A: 

Your SelectedValue should be a unique id of some sort, that doesn't change. The Text value that gets displayed to the user is something seperate, and can change if necessary without affecting your application, because you associate the id with your Order, not the displayed string value.

tbreffni
+5  A: 

I solved this exact same problem just two days ago. First, I moved the code that set the SelectedValue to a PreRender handler for the DropDownList. Then, I add logic to first check to see if the value is in the drop down list. If not, I add it.

Here's my code. ddSpecialty is my drop-down list, populated with "specialties" from the database. registration.Specialty is the specialty that the user chose, which may or may not be in the drop down, since that particular specialty may have been deleted since they last chose it.

protected void ddSpecialty_PreRender(object sender, EventArgs e)
{
    if (!ddSpecialty.Items.Contains(new ListItem(registration.Specialty)))
        ddSpecialty.Items.Add(registration.Specialty);
    ddSpecialty.SelectedValue = registration.Specialty;
}
Josh Hinman
+2  A: 

I'm not sure it's the same issue, but I had a similar sounding issue with trying to bind a DropDownList that I wanted to contain in a GridView. When I looked around I found a lot of people asking similar questions, but no robust solutions. I did read conflicting reports about whether you could intercept databinding, etc events. I tried most of them but I couldn'f find a way of intercepting or pre-empting the error.

I ended up creating a subclass of the ddl, intercepting the error from there hacking a fix.

Not tidy but it worked for my needs. I put the code up on my blog in case it's of help. link text

David
A: 
        if (ddl.Items.Contains(new ListItem(slectedFacility)))
            ddl.SelectedValue = slectedFacility;
A: 

To have to do these crazy things to handle the exception (and first to learn how to handle it) tells me there is something very wrong with the .NET web control model of programming.

+2  A: 

I've become very fond of the following little snippet for setting DropDownList values:

For non-DataBound (eg Items added manually):

ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(value));

For DataBound:

ddl.DataBound += (o,e) => ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(value));

I sure do wish though that ListControls in general didn't throw errors when you try to set values to somthing that isn't there. At least in Release mode anyways it would have been nice for this to just quietly die.

Josh