I am attempting to DataBind an asp:DropDownList with a Collections.Generic.List of System.Web.UI.WebControls.ListItems. The DataBind() is throwing this error.
System.ArgumentOutOfRangeException: 'ddlPlatinumOptions' has a SelectedValue which is invalid because it does not exist in the list of items.
.ascx
<asp:DropDownList ID="ddlPlatinumOptions" runat="server" AutoPostBack="true" width="100%"></asp:DropDownList>
.ascx.cs
public void BindPlatinumOptions()
{
ddlPlatinumOptions.DataTextField = "Text";
ddlPlatinumOptions.DataValueField = "Value";
ddlPlatinumOptions.DataSource = _platinumOptions;
ddlPlatinumOptions.DataBind(); // Throwing Error
}
presenter
MattressProtectionInfo standard = RF_ProtectionPlan.GetMattressPlanInfo(MattressId, false);
MattressProtectionInfo premium = RF_ProtectionPlan.GetMattressPlanInfo(MattressId, true);
List<ListItem> plans = new List<ListItem>();
if (standard != null)
{
plans.Add(new ListItem(standard.Price.ToString("C") + " - Standard 5-Year Platinum Protection", standard.ProductID.ToString()));
}
if (premium != null)
{
plans.Add(new ListItem(premium.Price.ToString("C") + " - Premium 5-Year Platinum Protection", premium.ProductID.ToString()));
}
_view.PlatinumOptions = plans;
_view.BindPlatinumOptions();
Data Example
Thing I have tried
I am grabbing at straws. It appears as if the databind is trying to select something inside of the dropdownlist that isn't there.
Is there an error in my code I'm not seeing? Any Ideas?
After facing this problem, too, I debugged the ASP.NET source code and found a flaw(?) in the ASP.NET source code (and, hence, the solution to our problem):
Internally, System.Web.UI.WebControls.Listcontrol caches the most recently used SelectedValue. So when a data binding occurs (which natively clears the SelectedValue property) after the SelectedValue has already been set from Request.Form[], the data binding operation tries to find and pre-select the previously cached item. Unfortunately it throws an exception when the cached value isn't found in the new DataSource list instead of silently leaving the current SelectedValue null value alone.
I guess they did that because when using ViewState and data source objects for data binding, the later data bind operation would remove the SelectedValue obtained by Request.Form[].
So, whenever you perform more than one data binding operation on a ListControl within a page lifecycle and when the data sources differ, then this exception occurs.
public virtual string SelectedValue
{
set
{
if (Items.Count != 0)
{
// at design time, a binding on SelectedValue will be reset to the default value on OnComponentChanged
if (value == null || (DesignMode && value.Length == 0))
{
ClearSelection();
return;
// !!! cachedSelectedValue is not getting reset here !!!
}
...
// always save the selectedvalue
// for later databinding in case we have viewstate items or static items
cachedSelectedValue = value;
}
}
Instead of:
dropDownBox.DataSource = ...;
dropDownBox.DataBind();
Write this:
dropDownBox.Items.Clear();
dropDownBox.SelectedValue = null;
dropDownBox.DataSource = ...;
dropDownBox.DataBind();
(The dropDownBox.Items.Clear(); operation is only required if dropDownBox.Items isn't already empty.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With