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 список вместо того, чтобы молча выходить из текущего SelectedValuenull ценность одна.

Я думаю, что они сделали это, потому что при использовании 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 еще не пусто.)

Другие вопросы по тегам