回发数据绑定错误:“确保在调用数据绑定之前将控件添加到页面。”
我有一个程序,允许用户使用几个下拉菜单来选择主题和属性,然后提取与这两个条件匹配的数据。在网格视图中,许多模板字段使用文本框进行即时编辑(提交按钮保存所有更改)以及带有绑定到参数的下拉列表的模板。这一切都在相当长的一段时间内顺利进行。
然后,我们更改了表中的一些数据(保留所有相同的字段名称),现在页面在启动时加载得非常好,但一旦您在任何钻取下拉列表中选择不同的内容,页面就会失败。我收到一条错误消息
“DropDownList 控件“TagDDL”没有命名容器。 确保在调用 DataBind 之前将控件添加到页面。”
(TagDDL 是 gridview 中模板字段中的下拉列表)。如果我只是删除此模板字段,我会在超链接字段上收到类似(尽管不同)的错误,删除它会给我带来好处绑定字段中的错误,所以显然它与任何一件事无关,
我的想法是它与数据绑定在回发时的工作方式有关,因为页面最初加载完美,下拉菜单具有“启用”。 PostBack' 和错误消息引用构建
Gridview 的 SqlDataSource
<asp:SqlDataSource ID="MasterTable" runat="server"
ConnectionString="<%$ ConnectionStrings:spvConnectionString %>"
SelectCommand="exec pmtv2.maintable_display 1, @IPG_Assigned, @CompetitorName, @enterprise_zone, @Banner, @BrandName"
<SelectParameters>
<asp:ControlParameter ControlID="ChooseBanner" Name="Banner" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseIPGs" Name="IPG_Assigned" PropertyName="SelectedValue" Type="Int32" />
<asp:ControlParameter ControlID="ChooseBrands" Name="BrandName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseComps" Name="CompetitorName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseZone" Name="enterprise_zone" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
有什么想法吗?
<div id="MasterDiv" style="width:90%">
<asp:GridView ID="MasterDisplay" runat="server"
AllowSorting="True" AutoGenerateColumns="False"
DataKeyNames="productKey,banner,enterprise_zone,userID" DataSourceID="MasterTable"
OnRowDataBound="MasterDisplay_RowDataBound"
OnSorting="MasterDisplay_Sorting"
class="mGrid" AlternatingRowStyle-CssClass="mGridAlt">
</AlternatingRowStyle>
<Columns>
<asp:TemplateField HeaderText="Description" SortExpression="productdescriptionlong">
<ItemTemplate>
<a href="javascript:openPopup('JustinPractice4.aspx?UPC=<%# Eval("UPC") %>
&banner=<%# Eval("banner") %>&enterprise_zone=<%# Eval("enterprise_zone") %>')"><%# Eval("productdescriptionlong")%></a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="BrandName" HeaderText="Brand"
SortExpression="BrandName" />
<asp:TemplateField HeaderText="New Price" SortExpression="new_base_retail">
<ItemTemplate>
<asp:TextBox ID="RWNextPrice" runat="server"
Text='<%# Bind("new_base_retail", "{0:N2}") %>' Width="60px"
class="calculate" onchange="lineItemRipple(this)"
Visible='<%# ShowBox %>'></asp:TextBox>
<asp:Label ID="RNextPrice" runat="server" Text='<%# Eval("new_base_retail", "{0:c}") %>'
Visible='<%# ShowLabel %>'></asp:Label>
<asp:HiddenField ID="lineCode" runat="server" Value='<%# Eval("line_code") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:ImageField DataImageURLField="unique_flags" HeaderText="Flags"
DataImageURLFormatString="Media/Images/{0}.png" SortExpression="unique_flags"/>
<asp:TemplateField HeaderText="Tag Type" SortExpression="tag_type">
<ItemTemplate>
<asp:DropDownList ID="TagDDL" runat="server"
DataSourceID="dimTags"
DataTextField="Tag_type_name"
DataValueField="Tag_type_name"
SelectedValue='<%#Bind("tag_type") %>'
visible='<%#ShowBox %>'>
</asp:DropDownList>
<asp:Label ID="TagR" runat="server"
Text='<%# Eval("tag_type") %>'
Visible='<%# ShowLabel %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Commit" runat="server" Text="Commit Changes" OnClick="Commit_Click"
class="button"/>
以及背后的相关代码:
protected void Page_Load(object sender, EventArgs e) {
ErrorMsg.Text = "test45";
}
protected void MasterDisplay_RowDataBound(object sender, GridViewRowEventArgs e) {
DataSourceSelectArguments sr = new DataSourceSelectArguments();
DataView dv = (DataView)CheckForCommit.Select(sr);
if (dv.Count != 0) {
CommittedOrNot.Text = dv[0][0].ToString();
}
//pulling results from a SqlDataSource confirming presence of data
//calculations to maintain a running tally of certain fields for later use
}
protected void Commit_Click(Object sender, EventArgs e) {
string tagValue = "FLAG";
foreach (GridViewRow gvr in MasterDisplay.Rows) {
tagValue = ((DropDownList)gvr.FindControl("TagDDL")).SelectedValue;
MasterDisplay.UpdateRow(gvr.RowIndex, false);
} //for every row, update it
MasterDisplay.DataBind();
}
I have a program that allows the user to use a few dropdowns to pick a topic and attribute, then the data are pulled that match on both of those conditions. In the gridview are a lot of templatefields use textboxes for instant editing (a submit button saves all changes) as well as a template with a dropdown bound to a parameter. This was all working hunky-dory for quite a while.
Then, we changed some of the data in the tables (keeping all the same field names) and now the page loads perfectly fine on launch but then as soon as you select something different in any of the drilldown dropdowns the page fails. I get an error saying
"The DropDownList control 'TagDDL' does not have a naming container.
Ensure that the control is added to the page before calling DataBind."
(TagDDL is the dropdown in the templatefield in gridview). If I simply remove this templatefield, I get a similar (though different) error on a hyperlinkfield, removing this gives me an error in a boundfield, so obviously it's not tied to any one thing.
My idea is that it has something to do with how databinding works on post-back, since the page loads perfectly initially, the dropdowns have 'Enable PostBack' and the error messages refer to DataBind. Any ideas?
The SqlDataSource that builds Gridview (leaving out the drilldown dropdowns for now)
<asp:SqlDataSource ID="MasterTable" runat="server"
ConnectionString="<%$ ConnectionStrings:spvConnectionString %>"
SelectCommand="exec pmtv2.maintable_display 1, @IPG_Assigned, @CompetitorName, @enterprise_zone, @Banner, @BrandName"
<SelectParameters>
<asp:ControlParameter ControlID="ChooseBanner" Name="Banner" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseIPGs" Name="IPG_Assigned" PropertyName="SelectedValue" Type="Int32" />
<asp:ControlParameter ControlID="ChooseBrands" Name="BrandName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseComps" Name="CompetitorName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseZone" Name="enterprise_zone" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
<div id="MasterDiv" style="width:90%">
<asp:GridView ID="MasterDisplay" runat="server"
AllowSorting="True" AutoGenerateColumns="False"
DataKeyNames="productKey,banner,enterprise_zone,userID" DataSourceID="MasterTable"
OnRowDataBound="MasterDisplay_RowDataBound"
OnSorting="MasterDisplay_Sorting"
class="mGrid" AlternatingRowStyle-CssClass="mGridAlt">
</AlternatingRowStyle>
<Columns>
<asp:TemplateField HeaderText="Description" SortExpression="productdescriptionlong">
<ItemTemplate>
<a href="javascript:openPopup('JustinPractice4.aspx?UPC=<%# Eval("UPC") %>
&banner=<%# Eval("banner") %>&enterprise_zone=<%# Eval("enterprise_zone") %>')"><%# Eval("productdescriptionlong")%></a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="BrandName" HeaderText="Brand"
SortExpression="BrandName" />
<asp:TemplateField HeaderText="New Price" SortExpression="new_base_retail">
<ItemTemplate>
<asp:TextBox ID="RWNextPrice" runat="server"
Text='<%# Bind("new_base_retail", "{0:N2}") %>' Width="60px"
class="calculate" onchange="lineItemRipple(this)"
Visible='<%# ShowBox %>'></asp:TextBox>
<asp:Label ID="RNextPrice" runat="server" Text='<%# Eval("new_base_retail", "{0:c}") %>'
Visible='<%# ShowLabel %>'></asp:Label>
<asp:HiddenField ID="lineCode" runat="server" Value='<%# Eval("line_code") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:ImageField DataImageURLField="unique_flags" HeaderText="Flags"
DataImageURLFormatString="Media/Images/{0}.png" SortExpression="unique_flags"/>
<asp:TemplateField HeaderText="Tag Type" SortExpression="tag_type">
<ItemTemplate>
<asp:DropDownList ID="TagDDL" runat="server"
DataSourceID="dimTags"
DataTextField="Tag_type_name"
DataValueField="Tag_type_name"
SelectedValue='<%#Bind("tag_type") %>'
visible='<%#ShowBox %>'>
</asp:DropDownList>
<asp:Label ID="TagR" runat="server"
Text='<%# Eval("tag_type") %>'
Visible='<%# ShowLabel %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Commit" runat="server" Text="Commit Changes" OnClick="Commit_Click"
class="button"/>
and the relevant code behind:
protected void Page_Load(object sender, EventArgs e) {
ErrorMsg.Text = "test45";
}
protected void MasterDisplay_RowDataBound(object sender, GridViewRowEventArgs e) {
DataSourceSelectArguments sr = new DataSourceSelectArguments();
DataView dv = (DataView)CheckForCommit.Select(sr);
if (dv.Count != 0) {
CommittedOrNot.Text = dv[0][0].ToString();
}
//pulling results from a SqlDataSource confirming presence of data
//calculations to maintain a running tally of certain fields for later use
}
protected void Commit_Click(Object sender, EventArgs e) {
string tagValue = "FLAG";
foreach (GridViewRow gvr in MasterDisplay.Rows) {
tagValue = ((DropDownList)gvr.FindControl("TagDDL")).SelectedValue;
MasterDisplay.UpdateRow(gvr.RowIndex, false);
} //for every row, update it
MasterDisplay.DataBind();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我实际提取绑定所需的数据之前尝试添加到 DDL 是一个简单的错误。稍微改变一下事情的顺序就可以了
It was a simple error of trying to add to a DDL before I had actually pulled the data needed to bind it. Changing the order of things slightly did the trick
我很高兴你找到了答案。我在运行时加载的 UserControl (ascx) 上遇到了类似的问题。我也对我的数据源和相应的sql数据源进行了更改。 (在我的例子中,我用实体模型替换了 sql 数据源。)
我发现我的一个控件可以毫无问题地绑定到新数据源(通过后面的代码)。代码如下所示:
但是,在同一个方法中,当调用 DataBind() 方法时,下一段代码将失败。代码如下:
事实证明,当我删除 SqlDataSource 对象之前的 ASCX 标记时,我未能删除下拉控件的 DataSourceID 属性中的引用。因此,当我调用 DataBind() 方法时,绑定引擎检查控件的属性,找到一个名称 DataSourceID,并立即在 UserControl 的控件层次结构中查找它。当绑定引擎找不到对象时,它会抛出异常“DropDownList 控件 [...] 没有命名容器...”
我承认这个特定的异常有些误导,因为它实际上是绑定器对于数据源要遵循哪些指令(隐藏的代码或 ascx 文件中的标记)感到困惑。
我希望这对一些观点有所帮助。 :)
I am glad you found your answer. I had a similar issue on a UserControl (ascx) that was being loaded a run-time. I, too, had made a change to my data source and the corresponding sql data sources. (In my case, I was replacing the sql data sources with an entity model.)
What I found was that one of my controls would bind to the new data source (via the code behind) with no problems. The code looked as follows:
However, in the same method, the next section of code would fail when the DataBind() method was called. The code looked as follows:
It turned out, that when I removed the prior ASCX markup for the SqlDataSource objects, I failed to remove the reference in the DataSourceID attribute of the drop down control. So when I called the DataBind() method, the binding engine checked the attributes of the control, found a name DataSourceID, and immediately went looking for it in the control hierarchy of the UserControl. When the binding engine failed to find the object, it threw the exception "The DropDownList control [...] does not have a naming container..."
I will admit that this particular exception is somewhat misleading, as it is really the binder being confused over which instructions to follow for the data source (the code behind, or the markup in the ascx file).
I hope this helps with some perspective. :)