GridView с DropDownList в EditItemTemplate

У меня есть GridView с adrpDownList в EditItemTemplate. Исходные данные находятся в этикетке и в режиме редактирования передаются в ddl. При нажатии кнопки редактирования я получил исключение: System.ArgumentOutOfRangeException: 'ddlCities' имеет SelectedValue, которое является недопустимым, поскольку оно не существует в списке элементов. Я нашел аналогичный вопрос здесь и адаптировал код к своим потребностям следующим образом (где город — это строка, полученная из метки в itemTemplate gridView):

 protected void gvClients_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (!string.IsNullOrEmpty(city))
        {
            ddlTemp = (DropDownList)e.Row.Cells[7].FindControl("ddlCities");
            if (ddlTemp != null)
            {

                ListItem item = ddlTemp.Items.FindByValue(city);
                if (item != null)
                {
                    item.Selected = true;

                }
            }
        }
    }

Чтобы заставить его работать, мне пришлось стереть SelectedValue = ‹%# Bind("City") %>, в противном случае вышеуказанное исключение возникло снова. Но теперь я хочу обновить свои данные в соответствии со значением, выбранным в ddl, и мне это не удается, потому что ddl не привязан ни к чему в источнике данных gridView. Буду очень признателен за помощь.


person Dov Miller    schedule 25.08.2011    source источник


Ответы (2)


Убедитесь, что вы привязываете раскрывающийся список, прежде чем пытаться установить его значение.

Control ddlCtrl = e.Row.FindControl("ddlCities");
if (ddlCtrl != null)
{
    DropDownList ddlCities = ddlCtrl as DropDownList;

    //using a datasource control
    CitiesDataSourceControl.DataBind();

    if (ddlCities.Items.Count > 0) 
    {
        ListItem item = ddlCities.Items.FindByValue("Boston");
        if (item != null)
            item.Selected = true;
    }
}
person James Johnson    schedule 25.08.2011
comment
@Bala R: Спасибо за комментарий. Я пересмотрел свой ответ. - person James Johnson; 25.08.2011
comment
DropDownList привязан к источнику данных через смарт-тег, и да, DataTextField и DataValueField также установлены там. - person Dov Miller; 25.08.2011
comment
@Dov Miller: Вы используете элемент управления источником данных? Смотрите отредактированный ответ. - person James Johnson; 25.08.2011
comment
ddl хорошо заполняет проблему обновления с него на источник данных gridView. То, что вы написали, не добавляет ничего существенного к тому, что я уже написал. Спасибо. - person Dov Miller; 25.08.2011
comment
@Dov Miller: Если вы не можете найти элемент в списке, это будет означать, что список еще не привязан, что оставляет вам два варианта: использовать привязку вручную в событии RowDataBound или установить выбранное значение в точка, в которой DropDown привязан к данным. Если вам нужен конкретный ответ, вы должны показать, как связан ваш список. - person James Johnson; 25.08.2011
comment
Мой dropDownList привязан к SqlDataSource, который получает данные, запрашивая таблицу в БД, содержащую список городов. Это в режиме редактирования gridView. В обычном режиме есть метка, привязанная к столбцу City таблицы клиентов в БД другим SqlDataSource. Когда я привязываю selectedValue ddl к столбцу городов с помощью ‹%# Bind(City) %›, я получаю сообщение об исключении, упомянутое выше, даже если город существует в списке. - person Dov Miller; 28.08.2011
comment
(Продолжение предыдущего комментария) Вот почему я использовал код, упомянутый в моем вопросе, и удалил ‹%# Bind(City) %›. Затем выбор преуспевает, но я не могу обновить столбец города таблицы клиентов в соответствии с вновь выбранным городом из ddl, потому что ddl не привязан к источнику данных клиентов. - person Dov Miller; 28.08.2011

Проблема, по-видимому, заключается в том, что данные моего города написаны справа налево (иврит), поэтому, когда метка ItemTemplate привязывается к данным, она добавляет начальные пробелы, и поэтому при привязке этого к ddl SelectedValue он не может найти элемент в элементах ddl список. Это я решил, перехватив событие RowEditing, извлек текст из метки с помощью функции Trim() и поместил обрезанное значение в строковую переменную с именем city. Затем в событии RowDataBound (код в вопросе) удалось выбрать правильный элемент в ddl. Поскольку ddl не привязан к данным из GridView, я не смог обновить столбец города. Для этого я перехватил событие SelectedIndexChanged ddl и поместил выбранное значение в объект ViewState с именем ViewState["CitySelect"]. Затем при обновлении я поймал событие RowUpdating следующим образом, что позволило успешно обновить строку, включая столбец города, в соответствии с изменением ddl города, даже если он не привязан к источнику данных gridView.

 protected void gvClients_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {

        GridViewRow row = gvClients.Rows[e.RowIndex];

        if (ViewState["CitySelect"] != null)
        {
            e.NewValues.Remove("city");
            string tempCity = (string)ViewState["CitySelect"];
            e.NewValues.Add("city",tempCity);
            row.Cells[7].Text = (string)e.NewValues["city"];
        }
        else
            row.Cells[7].Text = (string)e.OldValues["city"];
    }

Если кто-то может предложить что-то более простое, я был бы признателен.

person Dov Miller    schedule 30.08.2011