Как привязать данные к DropDownList в UpdatePanel внутри DetailsView - PullRequest
4 голосов
/ 06 августа 2010

Я использую 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();
}

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

Ответы [ 3 ]

1 голос
/ 06 августа 2010

Проблема в том, что когда вы связываете данные с раскрывающимся списком подкатегорий, контекст привязки данных отсутствует (см. здесь для получения дополнительной информации, обратите внимание на комментарии Дэвида Фаулера).Я не думаю, что 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 при вставке / обновлении.

Обновление: можно установить 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;
}

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

1 голос
/ 16 мая 2011

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

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

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

0 голосов
/ 06 августа 2010

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

...