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();
Пример данных
- Value = "21696" Text = "$ 99.95 - Стандартная 5-летняя платиновая защита" Значение = "21702" Текст = "$ 119.95 - Премиум 5-летняя платиновая защита"
Вещь, которую я пробовал
- Нулевой источник данных и привязка данных до моих данных, чтобы очистить все (сломал DataBind также) перемещение позиции DataTextField и DataValueField (трата времени - без изменений) объявление выбранного индекса 0 перед привязкой данных ddlPlatinumOptions.Items.Clear(); ddlPlatinumOptions.ClearSelection();
Я хватаюсь за соломинку. Кажется, что databind пытается выбрать что-то внутри выпадающего списка, которого нет.
Есть ли ошибка в моем коде, который я не вижу? Есть идеи?
Ну, это исключение вне диапазона. Вы устанавливаете значение SelectedIndex в значение по умолчанию в любой момент, прежде чем будете привязываться к DropDownList?
После этой проблемы я также отлаживал исходный код ASP.NET и обнаружил недостаток (?) В исходном коде ASP.NET (и, следовательно, решение нашей проблемы):
Internally, System.Web.UI.WebControls.Listcontrol
кэширует последний использованный SelectedValue
. Поэтому, когда происходит привязка данных (которая изначально очищает свойство SelectedValue
) после того, как SelectedValue
уже установлен из Request.Form[]
, операция привязки данных пытается найти и предварительно выбрать ранее сохраненный элемент. К сожалению, это генерирует исключение, когда кешированное значение не найдено в новом списке DataSource
вместо того, чтобы молча оставить текущее значение null
SelectedValue
.
Я думаю, они это сделали, потому что, используя 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();
(Операция dropDownBox.Items.Clear();
требуется только в том случае, если dropDownBox.Items
еще не пуст.)