Как привязать данные к DropDownList в UpdatePanel внутри DetailsView

Я использую DetailsView для вставки строк в базу данных. В строке есть поля id, subcategory_id и т. Д. Я хочу динамически заполнять выпадающий список ddl_subcategories, который используется в TemplateField. Выбранное значение элемента первого выпадающего списка ddl_categories используется как параметр для создания коллекции для ddl_subcategories. Я пробую использовать UpdatePanel, но метод DataBind возвращает ошибку «Методы привязки данных, такие как Eval (), XPath () и Bind (), могут использоваться только в контексте элемента управления привязкой данных».

Есть код веб-формы

<asp:DetailsView ID="dvw" runat="server" Height="50px" Width="125px" 
    AutoGenerateRows="False" DataSourceID="ods"
    DefaultMode="Insert" DataKeyNames="Section_id"
    OnDataBound="dvw_DataBound" OnItemUpdated="dvw_ItemUpdated" 
    OnItemCommand="dvw_ItemCommand">
    <Fields>
    <asp:TemplateField HeaderText="Category" >
       <ItemTemplate>
                 <asp:DropDownList ID="ddl_categories" runat="server" AutoPostBack="true" DataSourceID="ods_categories"
                  DataTextField="Name" DataValueField="Category_id" OnSelectedIndexChanged="category_select_index_changed"/>
       </ItemTemplate>
    </asp:TemplateField>            

    <asp:TemplateField HeaderText="Subcategory" >
        <ItemTemplate>
            <asp:UpdatePanel runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:DropDownList ID="ddl_subcategories" runat="server"                               
                          SelectedValue='<%# Bind("Subcategory_id") %>' />
                </ContentTemplate>
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="ddl_categories" EventName="SelectedIndexChanged" />
                </Triggers>
            </asp:UpdatePanel>
        </ItemTemplate>
    </asp:TemplateField>
...
 </Fields>
</asp:DetailsView>

Есть часть внутреннего кода:

protected void category_select_index_changed(object sender, EventArgs e)
{
    DropDownList ddl_categories = (DropDownList)dvw.FindControl("ddl_categories");
    List<SUBCATEGORY> sections =  SUBCATEGORY.Select_all_by_parameters(Int32.Parse(ddl_categories.SelectedValue));//Select all subcategories by id of category
    DropDownList ddl_subcategories= (DropDownList)dvw.FindControl("ddl_subcategories");

    ddl_subcategories.DataSource = sections;
    ddl_subcategories.DataTextField = "Name";
    ddl_subcategories.DataValueField = "Subcategory_id";
    ddl_subcategories.DataBind();
}

В чем моя ошибка? Спасибо.


person greatromul    schedule 06.08.2010    source источник
comment
У вас есть весь код? Я не вижу ddl_subcategories в вашем выделенном коде   -  person MCain    schedule 06.08.2010
comment
В ‹a href=страница stackoverflow.com/questions/1776407/ ‹/a› - вот ваш ответ. Вы должны правильно использовать DetailsView.   -  person Samiey Mehdi    schedule 05.08.2013
comment
В ‹a href=страница stackoverflow.com/questions/1776407/ ‹/a› - вот ваш ответ. вы должны правильно использовать из DetailsView.   -  person Samiey Mehdi    schedule 05.08.2013


Ответы (3)


Проблема в том, что когда вы привязываете данные в раскрывающемся списке подкатегорий, контекст привязки данных отсутствует (см. здесь для получения дополнительной информации обратите внимание на комментарии Дэвида Фаулера). Я не думаю, что UpdatePanel является проблемой, поскольку поведение одинаково с ним или без него (и если вы оберните весь DetailsView в UpdatePanel).

Решение состоит в том, чтобы загружать элементы по отдельности вместо привязки данных к элементу управления. Признаюсь, это кажется немного неуклюжим, но работает.

protected void category_select_index_changed(object sender, EventArgs e)
{
    DropDownList ddl_categories = (DropDownList)dvw.FindControl("ddl_categories");
    IEnumerable<SUBCATEGORY> sections = new SUBCATEGORY[] { new SUBCATEGORY() { Name = "First " + ddl_categories.SelectedValue, Subcategory_id = "1" }, new SUBCATEGORY() { Name = "Second", Subcategory_id = "2" } };
    DropDownList ddl_subcategories = (DropDownList)dvw.FindControl("ddl_subcategories");

    ddl_subcategories.Items.Clear();
    foreach (SUBCATEGORY cat in sections)
    {
        ddl_subcategories.Items.Add(new ListItem(cat.Name, cat.Subcategory_id));
    }
}

Лучшим вариантом было бы не использовать Bind в элементе управления, а просто установить значение в параметрах ObjectDataSource в Insert / Update.

Обновление: вы можете установить ObjectDataSource Ценность напрямую. Добавьте обработчик событий для OnInserting (или OnUpdating по мере необходимости) следующим образом:

protected void ods_OnInserting(object sender, ObjectDataSourceMethodEventArgs e)
{
    DropDownList ddl_subcategories = (DropDownList)dvw.FindControl("ddl_subcategories");
    e.InputParameters["Subcategory_id"] = ddl_subcategories.SelectedValue;
}

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

person sgriffinusa    schedule 06.08.2010
comment
Я пробовал так. Поля выпадающего списка заполнены правильно. Но форма отправила нулевое значение из раскрывающегося списка. Что есть причина? Еще один вопрос. Есть ли способ программно установить значение в ObjectDataSource? - person greatromul; 07.08.2010
comment
Если я не использую панель обновлений, ddl_subcategories вернет правильное значение. Но если я не использую панель обновлений, я не смогу реализовать поведение элементов управления без обратной передачи. - person greatromul; 07.08.2010
comment
Если я использую чистый AJAX (веб-сервисы и js) без панели обновлений, он работает. Но интересно, почему не работает с панелью обновлений. - person greatromul; 07.08.2010
comment
Причина, по которой первый способ не возвращает значения, заключается в том, что данные не заполняются в нужное время в жизненном цикле страницы (john-sheehan.com/blog/). Я не знаю, почему панель обновлений вызывает проблему, в моих тестах она не работает с панелью обновлений или без нее. Я обновил свой ответ подробностями о том, как программно установить значение ObjectDataSource при вставке / обновлении. - person sgriffinusa; 07.08.2010
comment
Хорошо спасибо. Я решил использовать чистый AJAX. Я подготовлю новый вопрос. Я обнаружил странную ошибку при использовании значения 0 в раскрывающемся списке. Вот мой новый пост stackoverflow.com/questions/3442019/ - person greatromul; 09.08.2010

Удалите Bind("DBFieldName") и добавьте следующую строку к YourDetailsView_ItemInserting, как показано ниже:

e.Values["DBFieldName"] = 
  ((DropDownList)YourDetailsView.Rows[1].FindControl("ddl_categories")).SelectedValue;

Примечание. Не забудьте заменить строки [1] на индекс поля выпадающего списка.

person Adel    schedule 16.05.2011

Попробуйте обернуть весь DetailsView панелью обновлений, чтобы увидеть, имеет ли это значение ...

person Brian Mains    schedule 06.08.2010