【问题标题】:How to bind data to DropDownList in UpdatePanel inside DetailsView如何将数据绑定到DetailsView内UpdatePanel中的DropDownList
【发布时间】:2011-03-26 11:22:13
【问题描述】:

我使用 DetailsView 在数据库中插入行。 Row 有字段 id、subcategory_id 等。我想动态填充在 TemplateField 中使用的下拉列表 ddl_subcategories。第一个下拉列表 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();
}

我的错误是什么? 谢谢。

【问题讨论】:

标签: asp.net data-binding drop-down-menu updatepanel


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    问题在于,当您对子类别下拉列表进行数据绑定时,没有 DataBinding 上下文(有关更多信息,请参阅 here,请注意 David Fowler 的 cmets)。我不认为 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;
    }
    

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

    【讨论】:

    • 我试过这样。下拉列表的字段已正确填写。但是表单从下拉列表中发送了空值。什么是理由?还有一个问题。有没有办法以编程方式在 ObjectDataSource 中设置值?
    • 如果我不使用更新面板,ddl_subcategories 返回正确的值。但是如果我不使用更新面板,我将无法在没有回发的情况下实现控件的行为。
    • 如果我使用没有更新面板的纯 AJAX(Web 服务和 js),它可以工作。但有趣的是为什么它不适用于更新面板。
    • 第一种方式没有返回值的原因是因为数据没有在页面生命周期的正确时间被填充(john-sheehan.com/blog/…)。我不知道为什么更新面板会导致问题,在我的测试中无论有没有更新面板都不起作用。我更新了我的答案,详细说明了如何在插入/更新时以编程方式设置 ObjectDataSource 值。
    • 好的,谢谢。我决定使用纯 AJAX。我会准备新的问题。我在下拉列表中使用 0 值时发现了奇怪的错误。这是我的新帖子stackoverflow.com/questions/3442019/…
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2012-06-08
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      相关资源
      最近更新 更多