DataBinding asp.net DropDownList из Списка ListItems, вызывающих System.ArgumentOutOfRangeException Ошибка
Я пытаюсь связать DataBind asp:DropDownList с Collections.Generic.List System.Web.UI.WebControls.ListItems. DataBind() выдает эту ошибку.
System.ArgumentOutOfRangeException: "ddlPlatinumOptions" имеет значение SelectedValue, которое недопустимо, поскольку его нет в списке элементов.
.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
}
ведущий
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();
Пример данных
- Значение = "21696" Текст = "99,95 $ - Стандартная 5 -летняя платиновая защита"
- Значение = "21702" Текст = "$119,95 - премиум 5 -летняя платиновая защита"
Что я пробовал
- Обнуление источника данных и привязки данных перед моими данными, чтобы очистить что-либо (также сломал dataBind)
- перемещение позиций DataTextField и DataValueField (трата времени - без изменений)
- объявить выбранный индекс 0 перед привязкой данных
- ddlPlatinumOptions.Items.Clear ();
- ddlPlatinumOptions.ClearSelection ();
Я хватаюсь за соломинку. Похоже, что база данных пытается выбрать что-то внутри выпадающего списка, которого там нет.
Есть ли в моем коде ошибка, которую я не вижу? Есть идеи?
2 ответа
Что ж, это исключение за пределами диапазона. Вы устанавливаете значение SelectedIndex в значение по умолчанию в любой точке, прежде чем привязываться к DropDownList?
Столкнувшись с этой проблемой, я также отладил исходный код ASP.NET и обнаружил недостаток (?) В исходном коде ASP.NET (и, следовательно, решение нашей проблемы):
Внутренне System.Web.UI.WebControls.Listcontrol
кеширует самые последние использованные SelectedValue
, Поэтому, когда происходит привязка данных (которая изначально очищает SelectedValue
собственность) после SelectedValue
уже был установлен из Request.Form[]
операция связывания данных пытается найти и предварительно выбрать ранее кэшированный элемент. К сожалению, это вызывает исключение, когда кэшированное значение не найдено в новом DataSource
список вместо того, чтобы молча выходить из текущего SelectedValue
null
ценность одна.
Я думаю, что они сделали это, потому что при использовании ViewState
и объекты источника данных для привязки данных, более поздняя операция привязки данных удалит SelectedValue
полученный Request.Form[]
,
Таким образом, всякий раз, когда вы выполняете более одной операции привязки данных на ListControl
в пределах жизненного цикла страницы, и когда источники данных различаются, возникает это исключение.
Вот краткий обзор кода ASP.NET:
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;
}
}
И вот решение:
Вместо:
dropDownBox.DataSource = ...;
dropDownBox.DataBind();
Напишите это:
dropDownBox.Items.Clear();
dropDownBox.SelectedValue = null;
dropDownBox.DataSource = ...;
dropDownBox.DataBind();
(The dropDownBox.Items.Clear();
операция требуется только если dropDownBox.Items
еще не пусто.)