Dropdown1 has a SelectedValue which is invalid because it does not exist in the list of items.

‘Dropdown1’ has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value

This error has been a real pain to deal with.  I finally have a work around and a guess at the underlying problem, and because I see that people are having this same problem I thought I would do a little writeup about it.

 

Obviously, if you look at the actual error message, there are cases when you can get this message and the problem is easy to solve.  e.g. you have a dropdown populated with EmploID values and you try to databind with: 

Value=’<%# Bind(“EmployeeName”) %>

 
Well of course that won’t work if all your values are integers and you are trying to set the value to “Bill Smith”.
 
But my problem was a bit more complicated.
 
I was building a web user control (aka ASCX) that was a “Location” dropdown.  The control basically contains a dropdown, and all the necessary logic to populate the dropdown, and I was trying to use this control inside the EditTemplate of a GridView.
 
To make things more complicated, in this case, I didn’t JUST want all the Locations, I also wanted to add a “Please Select” item to the list, with a value of 0.
 
But I kept getting the error above when the value was supposed to be 0.
 
I stepped through my code to try to find out what was going on.  I believe the issue is this:
 
On load, on value set, and on databind I call my “Populate” method.  This method sees if there are items in the dropdown.  If not, it gets a list from the database and binds to the dropdown.  It also checks if there is a “Please Select” item, and adds it if there isn’t one.
 
But still when Dropdown’s “DataBound” event was fired the last time, my manually added item had been removed.
 
So what I think what is happening is that :
1) I set the dropdown DataSource to a collection of business objects
2) I add the “Please Select” item
3) The dropdown is told to databind itself by the Gridview.
4) The dropdown says… “Oh, I do have a datasource, so I’m going to ditch my current list and rebind to that old collection”
5) The dropdown says “Holy shnikies, I am supposed to bind to value “0”, but I don’t have one!!”
 
I think there are 2 possible solutions.
 
1) I created an adapter class that only has Id and Description properties that are going to be used by the control, and I wrote a function to take my collection of business objects and build a collection of Adapters (adding my “Please Select”) to the list of adapters.  To see what I am talking about I will post this code below.
 
2) Manually add items to the dropdown instead of databinding, so that when the control is told to databind, it doesn’t have a datasource to use.
 
 
Here is my adapter code:
            '**** In my populate method
Me.LocationsDropdown.DataSource = LocationAdapter.LocationsToAdapters(locations)
Me.LocationsDropdown.DataTextField = "LocationDescriptionWithActiveAttribute"
Me.LocationsDropdown.DataValueField = "LocationId"
Me.LocationsDropdown.DataBind()



'*************************************
'*************************************




Private Class LocationAdapter
Public ciLocationId As Integer
Public csLocationDescriptionWithActiveAttribute As String
Public Property LocationId() As Integer
Get
Return ciLocationId
End Get
Set(ByVal value As Integer)
Me.ciLocationId = Value
End Set
End Property

Public Property LocationDescriptionWithActiveAttribute() As String
Get
Return csLocationDescriptionWithActiveAttribute
End Get
Set(ByVal value As String)
Me.csLocationDescriptionWithActiveAttribute = Value
End Set
End Property

Public Sub New(ByVal loc As Location)
Me.LocationId = loc.LocationId
Me.LocationDescriptionWithActiveAttribute = loc.LocationDescriptionWithActiveAttribute
End Sub
Public Sub New(ByVal Id As Integer, ByVal Desc As String)
Me.LocationId = Id
Me.LocationDescriptionWithActiveAttribute = Desc
End Sub

Public shared Function LocationsToAdapters(ByVal locations As List(Of Location)) As List(Of LocationAdapter)
Dim adapters As New List(Of LocationAdapter)
adapters.Add(New LocationAdapter(0, "--Location"))
For Each loc As Location In locations
adapters.Add(New LocationAdapter(loc))
Next
Return adapters
End Function

End Class
 
 
 
Advertisements

7 thoughts on “Dropdown1 has a SelectedValue which is invalid because it does not exist in the list of items.

  1. Thanks for the suggestion. Manually binding the items in the DropDownList fixed this for me.

    I had a State DropDownList in a MultiView that displayed the above error after editing one record and then re-selecting another record from a GridView via an edit command button.

    So instead of this:
    With ddlState
    .Items.Clear()
    .DataSource = ds
    .DataValueField = "StateCode"
    .DataTextField = "State"
    .DataBind()
    End With

    I did this:
    With ddlState
    .Items.Clear()
    For Each dr As MyWS.dsState.StateRow In ds.State.Rows
    .Items.Add(New ListItem(dr.State.ToString, dr.StateCode.ToString))
    Next
    End With

  2. We had this happen to us too. Nothing changed. Was working fine. Did an IIS Reset and it fixed the problem. VERY weird. Thoughts?

  3. haha loved these lines :
    ) The dropdown is told to databind itself by the Gridview.
    4) The dropdown says… "Oh, I do have a datasource, so I’m going to ditch my current list and rebind to that old collection"
    5) The dropdown says "Holy shnikies, I am supposed to bind to value "0", but I don’t have one!!"

    explained a lot to me.. was having the same problem in binding a datalist in expression web…. placing static options in the drop down would solve the problem but (100 records >< ) I need to learn how to code, and i can’t understand much code in asp.net (just started yesterday)

    anyway thanks!

  4. I am having a similar issue, except that I believe I can solve it if I can figure out how to access the selectedvalue in the code behind.

    I have two dropdowns that are visible under one condition and not under another. If I remove the selected value code runs well, of course when the visible one is displayed it does not select the needed element. So I believe if I could just trigger the selected value from the code behind when the visible condition is met I would be fine.

    Can you guide me to which ever object, method, sqldatabind – what ever it may be called that will let me access the same value that would be placed in the BIND("something") call from a SqlDataSource select stored procedure.

    Thanks so much for any direction!

  5. I think setting AppendDataBoundItems="true" in the droplist might work for you. You can include the zero "select an option" item in the markup, and the bound items will be added to that existing list, rather than replacing it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s