Ошибка: SelectedValue, который является недопустимым, потому что он не существует в списке элементов - PullRequest
5 голосов
/ 23 августа 2009

У меня есть Gridview, который привязывается к ObjectDataSource (objStudentDetails). В режиме редактирования / вставки Gridview одним из полей является DropDownList, который получает параметры списка выбора из справочной таблицы. У меня есть эта привязка DropDownList к другому элементу управления ObjectDataSource (objStateList), который представляет таблицу поиска. Он работает нормально, пока значение в objStudentDetails ObjectDataSource совпадает с одним из значений в objStateList ObjectDataSource, по крайней мере, в случае непустого строкового значения.

objStateList имеет следующие значения (из хранимого процесса, который его загружает - ID # 6 - пустая строка ''):

StateId     State
----------- -----
6             
4           AL
1           GA
3           KY
2           TN

Объект objStudentDetails имеет следующие значения (из хранимого процесса, который его загружает):

FirstName   LastName   State
----------- ---------- -----
tone        smith      TN

Или может иметь такой набор результатов (State - пустая строка - ''):

FirstName   LastName   State
----------- ---------- -----
jenny       johnson     

В первом наборе результатов objStudentDetails состояние DropDownList в EditItemTemplate отображается нормально. Однако во втором наборе результатов я получаю эту ошибку:

'ddlEditState' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value 

Я бы подумал, что, поскольку моя таблица поиска имеет значение с пустой строкой, значение objStudentDetails с пустой строкой для состояния будет соответствовать, но что-то не работает так, как я этого ожидаю.

Вот мой код EditItemTemplate из Gridview:

<EditItemTemplate>
  <asp:Panel ID="panEditState" runat="server">
    <asp:DropDownList ID="ddlEditState" runat="server" CssClass="GridviewDropdownlist"
      DataSourceID="objStateList" DataTextField="State" DataValueField="State"      
      SelectedValue='<%# Bind("State") %>'
      Width="50px">
</asp:DropDownList>
</asp:Panel>
</EditItemTemplate>

И objStateList, который вызывает метод, передающий параметр какой таблицы поиска для запроса:

<asp:ObjectDataSource ID="objStateList" runat="server" SelectMethod="GetDropdownData"     TypeName="AIMLibrary.BLL.DropdownData">
<SelectParameters>
<asp:Parameter Name="itemsToGet" DefaultValue="state" />
</SelectParameters>
</asp:ObjectDataSource>

Есть идеи?

Ответы [ 4 ]

9 голосов
/ 09 декабря 2009

Начните с установки для свойства DropDownLists AppendDataBoundItems значения true. Затем добавьте NULL ListItem, добавив следующий элемент <asp:ListItem> в каждый DropDownList, чтобы декларативная разметка выглядела следующим образом:

<asp:DropDownList ID="Categories" runat="server"
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
    DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
    AppendDataBoundItems="True">
    <asp:ListItem Value="">[nothing selected]</asp:ListItem>
</asp:DropDownList>
1 голос
/ 11 января 2012

Я подозреваю, что есть много разных сценариев, которые могут вызвать эту ошибку. В моем случае у меня был раскрывающийся список в поле шаблона. Раскрывающийся список был привязан к своему собственному источнику объектных данных, а его свойство selectedvalue было привязано к полю из собственного (отдельного) источника данных gridview.

Теперь, с моим конкретным сценарием, проблема была в состоянии гонки. Источник данных gridview был заполнен и привязан ДО того, как выпадет очередь. Это также означало, что выбранные значения раскрывающихся списков устанавливались ДО того, как элементы раскрывающихся списков были созданы с помощью их собственных привязок.

Я уверен, что должно быть лучшее решение, но у меня не было много времени для исследований. Я отключил сетку и выпадающие списки от их источников данных (то есть, удалив назначения из конструктора) и выбрал привязку программно. Таким образом, я могу явно связать выпадающие списки, чтобы значения их элементов были доступны при привязке самого вида сетки.

Пока все хорошо. Всего несколько дополнительных строк кода в Page_Load

0 голосов
/ 13 ноября 2014

ОК, поскольку это распространенная проблема, я думаю, стоит опубликовать ответ: после долгих осмотров я нашел два решения - ну, один патч и один реальный.

  1. заплаты: Установите параметр DDL AppendDataBoundItem=true и добавьте вручную один элемент в список (т. Е. «Пожалуйста, выберите» с нулевым значением):

    Пожалуйста, выберите </ asp: ListItem> </ asp: DropDownList>

Кажется, это работает примерно в 80% случаев. У меня была странная ситуация, когда мне приходилось обновлять существующий (и рабочий) запрос, используемый DDL, чтобы разрешить другое значение параметра - Query был чем-то похожим на SELECT ID, Name from EMPLOYEES where Department =@Department, и первоначально @Department мог быть равен только «Планировщикам» и «Мастерской» "- после добавления" Логистика "DDL загадочно перестал работать ТОЛЬКО для нового значения отдела.

  1. Правильное решение: связать DDL во время события GridView_RowDataBound (спасибо Эта статья

Мой параметр берется как текст из метки (настроен где-то еще)

    protected void GridView5_RowDataBound(object sender, GridViewRowEventArgs e)
    {

    //********** this  is a workaround for the annoying problem with dropdownlist in gidview without adding new item ************
    if (e.Row.RowType == DataControlRowType.DataRow && GridView5.EditIndex == e.Row.RowIndex)
    {
        DropDownList DropDownList5 = (DropDownList)e.Row.FindControl("DropDownList5");
        string query = "SELECT gkey as empID, name FROM [employees] where department=@department";
        SqlCommand command = new SqlCommand(query);
        command.Parameters.AddWithValue("@department", lblDepartment.Text);
        DropDownList5.DataSource = GetData(command);
        DropDownList5.DataTextField = "name";
        DropDownList5.DataValueField = "empID";
        DropDownList5.DataBind();
    }

И метод GetData:

   private DataTable GetData (SqlCommand cmd)
{
    string strConnString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter())
        {
            cmd.Connection = con;
            sda.SelectCommand = cmd;
            using (DataTable dt= new DataTable())
            {
                sda.Fill(dt);
                return dt;
            }
        }
    }
}
0 голосов
/ 05 июля 2011

AppendDataBoundItems = "True"> работает, но не во всех случаях. Создание выпадающего списка внутри GridView все еще остается загадкой, которую Microsoft должна решить. Говорят, что разработка в ASP намного быстрее, чем в PHP. Что ж, это мой третий день по этой маленькой проблеме, и до сих пор нет решения.

...