title: ASP.NET WebForms: Adding controls dynamically to a TableCell of a GridView and recovering them on the PostBack
body: <p>I have a <code>GridView</code> bound to a <code>DataSource</code>. The last column of it has a literal control with a comma-separated string of numbers. That string must be splitted and those numbers must be in their own <code>TextBox</code> (I don't know how many of them are in advance):</p>
  
  <p><a href="https://i.stack.imgur.com/Pb2wN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Pb2wN.png" alt="GridView"></a></p>
  
  <p>Here is the last column definition:</p>
  
  <pre><code>&lt;asp:TemplateField HeaderText="Cantidades"&gt;
      &lt;ItemTemplate&gt;
          &lt;asp:Literal ID="litCantidades" runat="server" Text='&lt;%# Eval("CANTIDADES") %&gt;'&gt;&lt;/asp:Literal&gt;
      &lt;/ItemTemplate&gt;
      &lt;ItemStyle HorizontalAlign="Left" /&gt;
  &lt;/asp:TemplateField&gt;
  </code></pre>
  
  <p>After, in the <code>RowDataBound</code> event, I do something like this:</p>
  
  <pre><code>private void CreaControlesCeldaCantidades(GridViewRow gridRow)
  {
      //Array of numbers got from the bound literal control in the cell.
      int[] cantidades = GetCantidadesFromRow(gridRow);
      TableCell cantidadesCell = gridRow.Cells[9];
  
      //I don't want the literal control anymore.
      cantidadesCell.Controls.Clear();
      int i = 0;
  
      //I create one TextBox per each number to put it
      //inside, so the user can edit it.
      foreach (var cantidad in cantidades)
      {
          var cantidadTextBox = new TextBox();
          cantidadTextBox.ID = "txtCantidad" + i++;
          cantidadTextBox.Text = cantidad.ToString();
          cantidadTextBox.Width = Unit.Pixel(10);
          cantidadTextBox.CssClass = "txtCantidad";
          cantidadesCell.Controls.Add(cantidadTextBox);
      }
  }
  </code></pre>
  
  <p>So far, so good. The problem comes on the <code>PostBack</code>. I try to recover the numbers edited by the user, but when I try to do it, all those <code>TextBox</code> created are gone:</p>
  
  <pre><code>private void ValidarEntradasNumericas()
  {
      foreach (GridViewRow row in grvMaterialesTareas.Rows)
      {
          var chkSistematico = (CheckBox)row.FindControl("chkSistematico");
          var txtSustitucion = (TextBox)row.FindControl("txtSustitucion");
          var sustitucion = 0;
  
          if (chkSistematico.Checked)
          {
              txtSustitucion.Text = "100";
          }
          else if (!int.TryParse(txtSustitucion.Text, out sustitucion))
          {
              throw new Exception("Uno de los códigos de sustitución indicados no es numérico. Por favor, corrija su valor.");
          }
  
          var cantidad = 0;
          var cantidadesCell = row.Cells[9];
  
          //Fails miserably and I don't know why :'(
          foreach (TextBox txtCantidad in cantidadesCell.Controls)
          {
              if (!int.TryParse(txtCantidad.Text, out cantidad))
              {
                  throw new Exception("Una de las cantidades indicadas no es numérica. Por favor, corrija su valor.");
              }
          }
      }
  }
  </code></pre>
  
  <p>I would like to know why that solution doesn't work and how I can make it work.</p>
  
  <p>Thanks in advance :)</p>