Introduction
This tip shows how to prevent DropDownList
data binding error during populating old data and - even more nicely – display the old data even if it does not exist in the list of items.
Background
When you bind a DropDownList
to a list of data, and you try to populate a value that is not on the list, you invariably will run into the error:
DropDownList has a SelectedValue which is invalid because it does not exist in the list of items.
To solve the problem, you have options:
- Remove the old value or change it to a corresponding data on the list.
- Add the value to the list.
- Check the value on the list during binding and set a default value if it is not on the list.
If we want to keep the old value as history record and also keep the list of data current, none of the solutions above are satisfied.
I wrote a function to check the value on the list and add it on the list if it does not exist during data binding. Here is the code:
protected string PreventUnlistedValueError(DropDownList li, string val)
{
if (li.Items.FindByValue(val) == null)
{
ListItem lit = new ListItem();
lit.Text = val;
lit.Value = val;
li.Items.Insert(li.Items.Count, lit);
}
return val;
}
Using the Code
Simple DropDownList Binding
HTML Code
<asp:DropDownList ID="DropDownList1" AutoPostBack="true"
runat="server" AppendDataBoundItems="true" >
<asp:ListItem Value="">select...</asp:ListItem>
<asp:ListItem Value="Item 1">Item 1</asp:ListItem>
<asp:ListItem Value="Item 2">Item 2</asp:ListItem>
<asp:ListItem Value="Item 3">Item 3</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server"
Text="Bind a Unlisted Value: item 5" OnClick="Button1_Click" />
Code Behind
protected void Button1_Click(object sender, EventArgs e)
{
string value = "Item 5";
DropDownList1.SelectedValue = PreventUnlistedValueError(DropDownList1, value);
}
Bind DropDownList in GridView
HTML
<asp:GridView ID="GridView1" Runat="server"
DataKeyNames="ProductID" ViewStateMode="Enabled"
AutoGenerateColumns="False" AllowPaging="True"
BorderWidth="1px" BackColor="White" OnRowEditing="GridView1_RowEditing"
CellPadding="3" BorderStyle="None" BorderColor="#CCCCCC">
<FooterStyle ForeColor="#000066" BackColor="White"></FooterStyle>
<PagerStyle ForeColor="#000066" HorizontalAlign="Left"
BackColor="White"></PagerStyle>
<HeaderStyle ForeColor="White" Font-Bold="True"
BackColor="#006699"></HeaderStyle>
<Columns>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
<asp:BoundField ReadOnly="True" HeaderText="ProductID"
InsertVisible="False" DataField="ProductID"
SortExpression="ProductID">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField HeaderText="ProductName" DataField="ProductName"
SortExpression="ProductName"></asp:BoundField>
<asp:TemplateField SortExpression="CategoryName" HeaderText="CategoryName">
<ItemTemplate>
<asp:Label Runat="server" Text='<%# Bind("CategoryName") %>'
ID="Label1"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" Runat="server" >
<asp:ListItem Value="">select...</asp:ListItem>
<asp:ListItem Value="Bikes">Bikes</asp:ListItem>
<asp:ListItem Value="Components">Components</asp:ListItem>
<asp:ListItem Value="Clothing">Clothing</asp:ListItem>
<asp:ListItem Value="Accessories">Accessories</asp:ListItem>
<asp:ListItem Value="Mountain Bikes">Mountain Bikes</asp:ListItem>
<asp:ListItem Value="Road Bikes">Road Bikes</asp:ListItem>
</asp:DropDownList>
<asp:HiddenField ID="hdCategory" runat="server"
Value ='<%# Eval("CategoryName") %>' />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle ForeColor="White" Font-Bold="True"
BackColor="#669999"></SelectedRowStyle>
<RowStyle ForeColor="#000066"></RowStyle>
</asp:GridView>
Code behind
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
BindGridView();
GridViewRow row = GridView1.Rows[e.NewEditIndex];
if (row != null)
{
DropDownList dpl = (DropDownList)row.FindControl("DropDownList2");
if (dpl != null)
{
DataRowView dataRow = (DataRowView)row.DataItem;
string val = ((HiddenField)row.FindControl("hdCategory")).Value.Trim();
dpl.SelectedValue = PreventUnlistedValueError(dpl, val);
}
}
}
Let's see the final output.
When you click on the button, item 5 is displayed on the DropDownList
even it is not on the current list item.
When you edit the GridView
row, some "old" Category names may not exist on the DropDownList
such as "Road Frames". Using this technique can be very convenient.
Hope this will be helpful for someone, thanks for reading.