‘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