Search code examples
c#asp.netgridviewhidden-fieldnested-gridview

Value of HiddenField Duplicated when called from Nested Gridvew Row Editing


Problem: I'm trying to get a value from a HiddenField object and set it to a string. A value of "foo" is being returned as "foo, foo".

Details: I have a Nested Gridview, and I'm trying to make the child Gridview editable. I have a method GetChildQuery(string id) which form the sql query to get the data for the Child Gridview, and I have the id bound to a HiddenField object in the HTML as so:

<asp:Gridview ID="gvChild" runat="server" AutoGenerateColumns="false" OnRowEditing = "gvChild_RowEditing">
 <Columns>
  <asp:TemplateField HeaderText="Name">
   <ItemTemplate>
    <asp:Label runat="server" ID="lblNameChild" Text='<% Eval("Name")%>'></asp:Label>
    <asp:HiddenField runat="server" ID="hidIDChild" Value ='<%# Bind("ItemID") %>' />
   </ItemTemplate>

   <EditItemTemplate>
     <asp:Label runat="server" ID="lblNameChildEdit" Text='<% Eval("Name")%>'></asp:Label>
    <asp:HiddenField runat="server" ID="hidIDChildEdit" Value ='<%# Bind("ItemID") %>' />
   </EditItemTemplate>
  </asp:TemplateField>

and I try to access it in the OnRowEditing method like:

protected void gvhild_RowEditing(object sender, GridViewEditEventArgs e) {
  Gridview child = sender as Gridview;
  string itemID = (child.Rows[e.NewEditIndex].FindControl("hidIDChild") as HiddenField).Value.ToString();
  string sql = GetChildQuery(itemID);
  child.EditIndex = e.NewEditIndex;
  child.DataSource = GetData(sql);
  child.DataBind();
}

The id is used in the WHERE clause of my SQL query, and therefore the output is incorrect if the value of the id is incorrect. I don't know I this problem is occurring because of how I bind data to the HiddenField or how I'm calling it from the RowEditing method, or something I'm completely overlooking.

Ref: To make the Nested Gridview, I mainly followed https://www.aspsnippets.com/Articles/Nested-GridView-Example-in-ASPNet-using-C-and-VBNet.aspx and https://www.aspforums.net/Threads/133072/Edit-Update-Delete-in-Nested-Child-GridView-in-ASPNet/ which has the general format for my GetData method as well.

EDIT: Problem subverted by replacing the string itemID instantiation to

string itemID= ((child.Rows[e.NewEditIndex].FindControl("hidIDChild") as HiddenField).Value.Split(','))[0].ToString();

essentially splitting the duplication, accessing the first element, converting that to a string, and setting that equal to y string itemID.

However while this subverts the problem, I would still appreciate anyone's feedback as to why the problem is occurring in the first place. Thanks!


Solution

  • You should look at your rendered html.

    When dealing with one gridview there is only ever one row open for editing at a time. And within a row's TemplateField the ItemTemplate and EditTemplate are mutually exclusive, that is to say that, when rendered, you will see only one or the other.

    Likewise in the code behind, you will only have access to either the ItemTemplate row or the EditTemplate row depending on which event you process on postback.

    The same rules apply to a nested/child Gridview.

    So for the case you describe, I assume you are trying to use some ID from the parent to build a query to populate the child. If so I do not believe you need any hidden fields at all. This ID fieldname from the parents query should be set in the DataKeyNames property of the parent gridview.

    You should then be able to pass the value to the procedure you are building for the child as

    protected void gvhild_RowEditing(object sender, GridViewEditEventArgs e) {
      string sql = GetChildQuery(gvParent.SelectedDataKey.Value);
    
      child.DataSource = GetData(sql);
      child.DataBind();
    
      // Given that you have just populated the child I do not think the 
      // following is accurate, but that's for you to decide
      child.SetEditRow(e.NewEditIndex);  
    }
    

    Hope this helps.