Problems creating/rendering a simple composite control
<p>I'm building a primarily data-entry application in asp.net. Because the design pane never accurately reflects the runtime appearance I do most of my work re page construction in the HTML view. Unfortunately endlessly adding tables, tr's td's labels and textboxes is very tedious, and I want to create some composite controls to do a lot of this work for me.</p>

<p>I am working on a composite to generate a div, table, tablerow with 4 cells, being<br>
a) a cell to indent what follows,<br>
b) a cell to contain a label<br>
c) a cell to contain a textbox, &amp;<br>
d) a cell to contain an asterisk label (for indicating a mandatory item)</p>

<p>The problem I have is that I'm unsure how to make the various components render correctly.</p>

<p>My code is as follows:</p>

<pre><code>  public class ReadyTextBox : WebControl, INamingContainer
  {
    #region private

    TextBox _txt = null;
    BaseLabel _lbl = null;
    Label _astrx = null;
    int _indent = 0;
    int _lblwidth = 0;
    int _txtwidth = 0;

    #endregion

    public ReadyTextBox()
    {
      txt = new TextBox();
      lbl = new BaseLabel();
      _astrx = new Label();
      _astrx.Text = "*";
      _astrx.ForeColor = System.Drawing.Color.Red;
    }

    #region properties

    public BaseLabel lbl {
      set { _lbl = value; }
      get { return _lbl; }
    }
    public TextBox txt {
      set { _txt = value; }
      get { return _txt; }
    }
    public string Caption {
      set { _lbl.Text = value + ":"; }
      get { return _lbl.Text; }
    }
    public int Indent {
      set { _indent = value; }
      get { return _indent; }
    }
    public int LabelWidth {
      set { _lblwidth = value; }
      get { return _lblwidth; }
    }
    public int TextWidth {
      set { _txtwidth = value; }
      get { return _txtwidth; }
    }
    public override bool Enabled {
      set { if (!(_txt == null)) _txt.Enabled = value; }
      get { if (!(_txt == null)) return _txt.Enabled; else return false; }
    }
    public string LabelClass {
      set { if (!(_lbl == null)) _lbl.CssClass = value; }
    }
    public bool Mandatory {
      set { if (!(_txt == null)) _astrx.Visible = value; }
    }
    public string TextClass {
      set { if (!(_txt == null)) _txt.CssClass = value; }
    }
    public int TextLen {
      set { if (!(_txt == null)) _txt.MaxLength = value; }
    }
    public TextBoxMode TextMode {
      set { if (!(_txt == null)) _txt.TextMode = value; }
    }
    public int TextRows {
      set { if (!(_txt == null)) _txt.Rows = value; }
    }

    #endregion

    #region rendering

    //build UI
    protected override void CreateChildControls()
    {
      Controls.Clear();

      HtmlGenericControl div = new HtmlGenericControl("div");
      div.ID = "div_" + this.ID;
      div.Attributes.Add("class", "clear");

      Table tbl = new Table();
      tbl.ApplyStyle(CreateControlStyle());
      tbl.CellSpacing = 1;
      tbl.CellPadding = 1;
      div.Controls.Add(tbl);

      TableRow r = new TableRow();
      tbl.Rows.Add(r);

      if (Indent == 0) Indent = 4;
      if (LabelWidth == 0) LabelWidth = 30;
      if (TextWidth == 0) TextWidth = 40;
      if (Indent + LabelWidth + TextWidth &gt; 99) throw new Exception("Component widths exceed 99%, for control: " + this.ID);

      TableCell c = new TableCell();
      c.Width = Unit.Percentage(Indent);
      r.Cells.Add(c);

      c = new TableCell();
      c.Width = Unit.Percentage(LabelWidth);
      r.Cells.Add(c);
      c.Controls.Add(lbl);

      c = new TableCell();
      c.Width = Unit.Percentage(TextWidth);
      r.Cells.Add(c);
      c.Controls.Add(txt);

      c = new TableCell();
      c.Width = Unit.Percentage(100 - (Indent + LabelWidth + TextWidth));
      r.Cells.Add(c);
      c.Controls.Add(_astrx);
    }

    //render UI
    protected override void Render(HtmlTextWriter writer)
    {
      //these statements all run, but by themselves, nothing is rendered.  
      base.EnsureChildControls();

      PrepareForRender();

      RenderContents(writer);


      //this code doesnt work; for some reason controls.count is 0 at this point
      //if (this.Controls.Count != 1) return;

      //HtmlGenericControl div = (HtmlGenericControl)this.Controls[0];
      //div.RenderControl(writer);
      //Table t = (Table)div.Controls[0];
      //t.RenderControl(writer);
      //TableRow r = t.Rows[0];
      //r.RenderControl(writer);
      //TableCell c = r.Cells[0];
      //c.RenderControl(writer);
      //c = r.Cells[1];
      //c.RenderControl(writer);
      //Label l = (c.Controls[0] as Label);
      //l.RenderControl(writer);
      //c = r.Cells[2];
      //c.RenderControl(writer);
      //TextBox x = (TextBox)c.Controls[0];
      //x.RenderControl(writer);
      //c = r.Cells[3];
      //c.RenderControl(writer);
      //l = (c.Controls[0] as Label);
      //l.RenderControl(writer);


      //these statements work, but the controls are rendered 
      //without the indentation &amp; width sizing intended.
      lbl.RenderControl(writer);
      txt.RenderControl(writer);
      _astrx.RenderControl(writer);
    }

    protected virtual void PrepareForRender()
    {
      if (Controls.Count != 1) return;

      HtmlGenericControl div = (HtmlGenericControl)Controls[0];
      Table t = (Table)div.Controls[0];
      t.CopyBaseAttributes(this);
      if (ControlStyleCreated) t.ApplyStyle(ControlStyle);

      TableRow r = t.Rows[0];
      BaseLabel b = (r.Cells[1].Controls[0] as BaseLabel);
      if (b != null) b.ForeColor = ForeColor;

      TextBox tb = (r.Cells[2].Controls[0] as TextBox);
      if (tb != null) b.ForeColor = System.Drawing.Color.Black;

      Label l = (r.Cells[3].Controls[0] as Label);
      if (l != null) l.ForeColor = System.Drawing.Color.Red;
    }

    #endregion
  }
}
</code></pre>

<p>Can anyone point out the problem is, or give me a solution or solution snippet? I haven't managed to find a useful example on the web. </p>
