我有一个程序允许用户使用一些下拉菜单来选择一个主题和属性,然后在这两个条件下拉出匹配的数据。在gridview中有很多模板字段使用文本框进行即时编辑(提交按钮保存所有更改)以及带有下拉参数的模板。这一切都在很长一段时间内都很有效。
然后,我们更改了表中的一些数据(保留了所有相同的字段名称),现在页面在启动时加载完全正常,但是一旦您在任何深入分析下拉列表中选择了不同的页面,页面就会失败。我收到错误说
“DropDownList控件'TagDDL'没有命名容器。 确保在调用DataBind之前将控件添加到页面中。“
(TagDDL是gridview中模板字段的下拉列表)。如果我只是删除这个模板字段,我在超链接字段上得到一个类似的(虽然不同)错误,删除它会在boundfield中出现错误,所以很明显它并没有绑定任何一件事。
我的想法是它与数据绑定如何在回发后工作有关,因为页面最初加载完美,下拉列表有“启用PostBack”,错误消息引用DataBind。有什么想法吗?
构建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();
}
答案 0 :(得分:0)
在我实际提取绑定它所需的数据之前尝试添加到DDL是一个简单的错误。稍微改变一下事情的顺序
答案 1 :(得分:0)
我很高兴你找到了答案。我在正在加载运行时的UserControl(ascx)上遇到了类似的问题。我也改变了我的数据源和相应的sql数据源。 (就我而言,我正在用实体模型替换sql数据源。)
我发现我的一个控件将绑定到新数据源(通过后面的代码)没有问题。代码如下:
gridSomeData.DataSource = controller.GetListOfAssociatedParts();
gridSomeData.DataBind();
但是,在同一方法中,调用DataBind()方法时,下一部分代码将失败。代码如下:
drpDataList.DataSource = controller.GetListOfParts();
drpDataList.DataTextField = "PartID"
drpDataList.DataValueField = "PartKey"
drpDataList.DataBind();
事实证明,当我删除SqlDataSource对象的先前ASCX标记时,我无法删除下拉控件的DataSourceID属性中的引用。因此,当我调用DataBind()方法时,绑定引擎检查了控件的属性,找到了一个名称DataSourceID,并立即在UserControl的控件层次结构中查找它。当绑定引擎找不到对象时,它抛出异常“DropDownList控件[...]没有命名容器......”
我承认这个特殊的例外有点误导,因为它实际上是关于数据源(后面的代码或ascx文件中的标记)遵循哪些指令的混淆。
我希望这有助于一些观点。 :)