如何将数据绑定到DetailsView内UpdatePanel中的DropDownList

发布于 2024-09-13 09:22:08 字数 2420 浏览 6 评论 0原文

我使用 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();
}

我的错误是什么? 谢谢。

I use DetailsView to insert rows in database. Row has fields id, subcategory_id etc. I want to fill dynamically dropdownlist ddl_subcategories, which is used in TemplateField. Selected item value of first dropdownlist ddl_categories is used as parameter for generating collection for ddl_subcategories. I try it with using UpdatePanel, but method DataBind returns error "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.".

There's code of web form

<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>

There is part of behind-code:

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();
}

What is my error?
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

同展鸳鸯锦 2024-09-20 09:22:08

问题是,当您对子类别下拉列表进行数据绑定时,没有数据绑定上下文(请参阅此处< /a> 了解更多信息,请关注 David Fowler 的评论)。我不认为 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< 添加事件处理程序/a> (或 OnUpdating 根据需要)如下:

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

我现在无法实际测试它,但它应该接近。

The problem is that when you are data binding the subcategories dropdown, there is no DataBinding Context (see here for more info, pay attention to David Fowler's comments). I don't think the UpdatePanel is the issue as the behavior is the same with or without it (and if you wrap the entire DetailsView in an UpdatePanel).

A solution is to load the items individually instead of data binding the control. It seems a little clumsy, I admit, but it does work.

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));
    }
}

A better option would be to not use Bind in the control, and just set the value in the ObjectDataSource's parameters on Insert/Update.

Update: You can set the ObjectDataSource value directly. Add an event handler for the OnInserting (or OnUpdating as needed) as follows:

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

I can't actually test this right now, but it should be close.

深海少女心 2024-09-20 09:22:08

删除 Bind("DBFieldName") 并将以下行添加到 YourDetailsView_ItemInserting 中,如下所示:

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

注意:不要忘记将 Rows[1] 替换为下拉列表模板字段索引。

Remove the Bind("DBFieldName") and add the following line to the YourDetailsView_ItemInserting like the following:

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

Note: Don't forget to replace the Rows[1] to your Dropdown templete field index.

2024-09-20 09:22:08

尝试用更新面板包裹整个DetailsView,看看这是否有所不同......

Try wrapping the entire DetailsView with the update panel to see if that makes a difference...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文