When you bind a dropdownlist to a table of data, and you try to edit an entry that contains data that has been deleted, you invariably will run into the error: 'dropdownlist1' has a SelectedValue which is invalid because it does not exist in the list of items.
Consider the following example:
You have a series of Events that are displayed in a calendar, where each event can have a Category. You provide your users the ability to edit their events, and administrators the ability to edit categories.
When creating a new event you would have a dropdownlist that references the categories table like so:
<asp:DropDownList ID="ddlCategory" runat="server" Style="width: 150px;" CssClass="TextField"
SelectedValue='<%# Bind("Category") %>' DataSourceID="dsPopulateEventCategories"
DataTextField="Name" DataValueField="Name" AppendDataBoundItems="true">
<asp:ListItem Text="Please Select" Value=""></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="dsPopulateEventCategories" runat="server"
ConnectionString="<%$ ConnectionStrings:EvonetConnectionString %>"
SelectCommand="SELECT Name from [T_Categories]"></asp:SqlDataSource>
The same code would be used in your EditItemTemplate for your Formview in case the user wants to change the category. But if an administrator deletes or renames the category in the meantime then you get the following error:
'ddlCategory' has a SelectedValue which is invalid because it does not exist in the list of items
This is basically because the dropdownlist populates the categories from the category table - and the category that you have bound to your dropdownlist doesn't exist in that table.
To solve the problem neatly, first of all remove the SelectedValue property for your dropdownlist to remove your binding. Your dropdownlist then beomes:
<asp:DropDownList ID="ddlCategory" runat="server" Style="width: 150px;" CssClass="TextField"
DataSourceID="dsPopulateEventCategories" DataTextField="Name" DataValueField="Name"
AppendDataBoundItems="true">
<asp:ListItem Text="Please Select" Value=""></asp:ListItem>
</asp:DropDownList>
Secondly, in the PreRender subroutine for your Formview, add some code which will search through the data items bound to your dropdownlist, and if your category isn't found then display the "Please Select" option:
Protected Sub Formview1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) & _
Handles Formview1.PreRender
If Formview1.CurrentMode = FormViewMode.Edit Then
Dim rowView As DataRowView = CType(Formview1.DataItem, DataRowView)
If Not IsNothing(rowView) AndAlso Not IsNothing(CType(Formview1. & _
FindControl("ddlCategory"), DropDownList).Items. & _
FindByValue(rowView("Category").ToString())) Then
CType(Formview1.FindControl("ddlCategory"), DropDownList).SelectedValue & _
= rowView("Category").ToString()
End If
End If
End Sub
The final step is to save the selected category back into the database when the user clicks the Save button to complete editing:
Protected Sub Formview1_ItemUpdating(ByVal sender As Object, ByVal e As & _
System.Web.UI.WebControls.FormViewUpdateEventArgs) & _
Handles Formview1.ItemUpdating
e.NewValues("Category") = CType(formview1.FindControl("ddlCategory"), & _
DropDownList).SelectedValue
End Sub
Hope this helps!
Bartek Marnane