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