title: Can't get values out of dynamically added textbox
body: <p>Try as I might I can't get the values out of my dynamically added textboxes. I've tried enabling the ViewState in all the containing controls as well as adding the textbox values to the ViewState in the Page_Init event, but the Text property always comes up empty. Here's my code behind page...</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using O2S.Components.PDF4NET;
  using O2S.Components.PDF4NET.Graphics;
  using O2S.Components.PDF4NET.Graphics.Fonts;
  using O2S.Components.PDF4NET.Graphics.Shadings;
  using O2S.Components.PDF4NET.Graphics.Shapes;
  
  namespace PDFFormToGrid
  {
      public partial class Form : System.Web.UI.Page
      {
          private static double leftMargin = 15;
          private static double rightMargin = 15;
          private static double topMargin = 20;
          private static double minBottomMargin = 20;
          private static double rowHeight = 30;
          private static double headerHeight = 30;
          private static double firstPageTopOffset = 50;
          private static double[] columnsWidth = { 120, 120, 120, 120 };
          private static string[] columnsHeader = { "Name", "Phone Number", "Address", "Company" };
          private static List&lt;Control&gt; panels = new List&lt;Control&gt;();
          private static List&lt;TextBox&gt; fields = new List&lt;TextBox&gt;();
  
          protected void Page_Load(object sender, EventArgs e)
          {
              if (!Page.IsPostBack)
              {
                  panels.Clear();
              }
          }
  
          protected void btnSubmit_Click(object sender, EventArgs e)
          {
              PDFDocument form = CreatePDF(this);
  
              Response.ContentType = "application/x-msdownload";
              Response.AddHeader("content-disposition", "attachment;filename=form.pdf");
              form.Save(Response.OutputStream);
              Response.Flush();
              Response.End();
          }
  
          private static PDFDocument CreatePDF(Form form)
          {
              // Create the PDF document
              PDFDocument doc = new PDFDocument();
  
              // Create the graphics objects
              PDFFont titleFont = new PDFFont(PDFFontFace.Helvetica, 35);
              PDFBrush purpleTitleBrush = new PDFBrush(new PDFRgbColor(19, 19,105));
  
              formatDoc(doc);
  
              // Create first page of report
              PDFPage page = doc.AddPage();
  
              formatPage(page, titleFont, purpleTitleBrush);
  
              DrawReportRows(doc, page, panels);
  
              return doc;
          }
  
  
          private static void formatDoc(PDFDocument doc)
          {
              doc.SerialNumber = "Serial Number Goes Here";
              doc.PageOrientation = PDFPageOrientation.Landscape;
          }
  
          private static void formatPage(PDFPage page, PDFFont font, PDFBrush brush)
          {
              // Draw title of report
              page.Canvas.DrawText("Applicant", font, null, brush, page.Width / 2, 
                  15, 0, PDFTextAlign.TopCenter);
  
              // Draw report header
              DrawReportHeader(page, firstPageTopOffset);
          }
  
          private static void DrawReportHeader(PDFPage page, double headerTopOffset)
          {
              // Create the graphics objects
              PDFFont headerFont = new PDFFont(PDFFontFace.Helvetica, 12);
              headerFont.Bold = true;
              PDFPen borderColor = new PDFPen(new PDFRgbColor(), 4);
              PDFBrush textColor = new PDFBrush(new PDFRgbColor());
              PDFBrush headerFill = new PDFBrush(new PDFRgbColor(192, 192, 193));
  
              // Draw the header
              page.Canvas.DrawRectangle(borderColor, headerFill, leftMargin, headerTopOffset,
                  page.Width - leftMargin - rightMargin, headerHeight);
  
              double xOffset = leftMargin;
              // Draw the column separators
              for (int i = 0; i &lt; columnsWidth.Length - 1; i++)
              {
                  xOffset = xOffset + columnsWidth[i];
                  page.Canvas.DrawLine(borderColor, xOffset, headerTopOffset,
                      xOffset, headerTopOffset + headerHeight);
              }
  
              xOffset = leftMargin;
              // Draw the columns header
              for (int i = 0; i &lt; columnsWidth.Length; i++)
              {
                  page.Canvas.DrawText(columnsHeader[i], headerFont, null, textColor,
                      xOffset + columnsWidth[i] / 2, headerTopOffset + headerHeight / 2, 0, PDFTextAlign.MiddleCenter);
                  xOffset = xOffset + columnsWidth[i];
                  xOffset = xOffset + columnsWidth[i];
              }
  
          }
  
          private static void DrawReportRows(PDFDocument doc, PDFPage page, List&lt;Control&gt; panels)
          {
              // Get number of forms - there's one more than count because of the initial form
              int numForms = panels.Count;
  
              double rowOffset = firstPageTopOffset + headerHeight;
              for (int i = 0; i &lt; numForms; i++)
              {
                  if (rowOffset + rowHeight &gt; page.Height - minBottomMargin)
                  { // not enough space to draw a new row, then create a new page, 
                      // draw the header, then draw the rows.
                      page = doc.AddPage();
                      DrawReportHeader(page, topMargin);
                      rowOffset = topMargin + headerHeight;
                  }
                  DrawReportRow(page, rowOffset, panels[i]);
                  rowOffset = rowOffset + rowHeight;
              }
          }
  
          private static void DrawReportRow(PDFPage page, double topOffset, Control panel)
          {
              // Create the graphic objects
              PDFFont fontText = new PDFFont(PDFFontFace.Helvetica, 12);
              PDFPen borderColor = new PDFPen(new PDFRgbColor(), 1);
              PDFBrush textColor = new PDFBrush(new PDFRgbColor());
              PDFBrush headerFill = new PDFBrush(new PDFRgbColor(192, 192, 192));
  
              // Draw rows borders
              PDFPoint[] points = { new PDFPoint( leftMargin, topOffset ), 
                                    new PDFPoint( leftMargin, topOffset + rowHeight), 
                                    new PDFPoint( page.Width - rightMargin, topOffset + rowHeight ), 
                                    new PDFPoint( page.Width - rightMargin, topOffset )};
              page.Canvas.DrawLines(borderColor, points);
  
              double xOffset = leftMargin;
              // Draw the columns separators
              for (int i = 0; i &lt; columnsWidth.Length - 1; i++)
              {
                  xOffset = xOffset + columnsWidth[i];
                  page.Canvas.DrawLine(borderColor, xOffset, topOffset,
                      xOffset, topOffset + rowHeight);
              }
  
              // Get all form fields from panel
              fields.Clear();
              GetFormFields(panel);
  
              xOffset = leftMargin;
              // Draw the columns header
              for (int i = 0; i &lt; columnsWidth.Length; i++)
              {
                  // Get ith field text 
                  string fieldText = fields[i].Text;
                  page.Canvas.DrawText(fieldText, fontText, null, textColor,
                      xOffset + 2, topOffset + rowHeight / 2, 0, PDFTextAlign.MiddleLeft);
                  xOffset = xOffset + columnsWidth[i];
              }
          }
  
          private static void GetFormFields(Control panelControl)
          {
              ControlCollection controls = panelControl.Controls;
              foreach (Control childControl in panelControl.Controls)
              {
                  if (childControl.GetType().ToString() == "System.Web.UI.WebControls.TextBox")
                  {
                      TextBox txt = childControl as TextBox;
                      fields.Add(txt);
                  }
                  else
                  {
                      GetFormFields(childControl);
                  }
              }
          }
  
          protected void btnAddForm_Click(object sender, EventArgs e)
          {
              // Create Labels
              Label lblName = new Label();
              lblName.Text = "NAME:";
              Label lblNumber = new Label();
              lblNumber.Text = "NUMBER:";
              Label lblAddress = new Label();
              lblAddress.Text = "ADDRESS:";
              Label lblCompany = new Label();
              lblCompany.Text = "COMPANY:";
  
              // Create Text Boxes
              TextBox txtName = new TextBox();
              TextBox txtNumber = new TextBox();
              TextBox txtAddress = new TextBox();
              TextBox txtCompany = new TextBox();
  
              // Create submit button
              Button btnSubmit = new Button();
              btnSubmit.Text = "SUBMIT";
  
              // Create panel and add controls
              Panel pnlForm = new Panel();
              pnlForm.EnableViewState = true;
              pnlForm.Controls.Add(lblName);
              pnlForm.Controls.Add(txtName);
              pnlForm.Controls.Add(new LiteralControl("&lt;br /&gt;&lt;br /&gt;"));
              pnlForm.Controls.Add(lblNumber);
              pnlForm.Controls.Add(txtNumber);
              pnlForm.Controls.Add(new LiteralControl("&lt;br /&gt;&lt;br /&gt;"));
              pnlForm.Controls.Add(lblAddress);
              pnlForm.Controls.Add(txtAddress);
              pnlForm.Controls.Add(new LiteralControl("&lt;br /&gt;&lt;br /&gt;"));
              pnlForm.Controls.Add(lblCompany);
              pnlForm.Controls.Add(txtCompany);
              pnlForm.Controls.Add(new LiteralControl("&lt;hr /&gt;"));
              pnlForm.Controls.Add(new LiteralControl("&lt;br /&gt;&lt;br /&gt;"));
              panels.Add(pnlForm);
  
              foreach (Control panel in panels)
              {
                  phFormContent.Controls.Add(panel);
              }
  
          }
  </code></pre>
  
  <p>TextBoxes are added in the btnAddForm_Click() function, and inside of DrawReportRow() (which is itself triggered by another button click event) GetFormFields() is called, which adds all the dynamically added TextBoxes to a static List. Here's the .aspx file....</p>
  
  <pre><code>&lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Form.aspx.cs" Inherits="PDFFormToGrid.Form" EnableViewState="true" %&gt;
  
  &lt;!DOCTYPE html&gt;
  
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head runat="server"&gt;
      &lt;title&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form id="form1" runat="server"&gt;
          &lt;asp:PlaceHolder ID="phFormContent" runat="server" EnableViewState="true"&gt;
              &lt;asp:Panel ID="Panel1" runat="server" EnableViewState="true"&gt;
                  &lt;asp:Label ID="lblName" runat="server" Text="NAME:"&gt;&lt;/asp:Label&gt;
                  &lt;asp:TextBox ID="txtName" runat="server"&gt;&lt;/asp:TextBox&gt;
                  &lt;br /&gt;&lt;br /&gt;
                  &lt;asp:Label ID="lblNumber" runat="server" Text="NUMBER:"&gt;&lt;/asp:Label&gt;
                  &lt;asp:TextBox ID="txtNumber" runat="server"&gt;&lt;/asp:TextBox&gt;
                  &lt;br /&gt;&lt;br /&gt;
                  &lt;asp:Label ID="lblAddress" runat="server" Text="ADDRESS:"&gt;&lt;/asp:Label&gt;
                  &lt;asp:TextBox ID="txtAddress" runat="server"&gt;&lt;/asp:TextBox&gt;
                  &lt;br /&gt;&lt;br /&gt;
                  &lt;asp:Label ID="lblCompany" runat="server" Text="COMPANY:"&gt;&lt;/asp:Label&gt;
                  &lt;asp:TextBox ID="txtCompany" runat="server"&gt;&lt;/asp:TextBox&gt;
                  &lt;hr /&gt;
                  &lt;br /&gt;&lt;br /&gt;
              &lt;/asp:Panel&gt;
          &lt;/asp:PlaceHolder&gt;
          &lt;br /&gt;&lt;br /&gt;
          &lt;asp:Button ID="btnAddForm" runat="server" Text="Add Form" OnClick="btnAddForm_Click" /&gt;
          &lt;asp:Button ID="btnSubmitForms" runat="server" Text="Submit Forms" OnClick="btnSubmit_Click" /&gt;
      &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>