创建/渲染简单复合控件时出现问题

时间:2011-10-13 04:26:17

标签: asp.net

我正在asp.net中构建一个主要的数据输入应用程序。由于设计窗格从未准确反映运行时外观,因此我在HTML视图中进行了大部分工作。不幸的是,无休止地添加表格,tr的td标签和文本框非常繁琐,我想创建一些复合控件来为我做很多这项工作。

我正在研究一个复合材料来生成一个包含4个单元格的div,table,tablerow a)缩小后面的单元格,
b)包含标签的单元格 c)包含文本框的单元格,&
d)包含星号标签的单元格(用于指示强制项目)

我遇到的问题是我不确定如何正确渲染各种组件。

我的代码如下:

  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 > 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 & 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
  }
}

任何人都可以指出问题是,还是给我一个解决方案或解决方案片段?我还没有在网上找到一个有用的例子。

1 个答案:

答案 0 :(得分:0)

我在解决了一个相应简单的复合标签+文本框控件的相关示例后解决了这个问题,在这里:http://www.blog.ingenuitynow.net/Custom+Server+Controls+CreateChildControls+Or+Render.aspx

我已经将逻辑更改为不创建html控件,然后尝试渲染它们,通过渲染进行简单创建,如下所示:以下代码替换原始代码中的渲染代码区域。

protected override void CreateChildControls()
{
  Controls.Clear();
  Controls.Add(txt);
  Controls.Add(lbl);
  Controls.Add(_astrx);
  base.CreateChildControls();
}

//render UI
protected override void Render(HtmlTextWriter writer)
{
  EnsureChildControls();
  AddAttributesToRender(writer);

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

  writer.AddAttribute(HtmlTextWriterAttribute.Class, "clear", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Div);
  writer.AddAttribute(HtmlTextWriterAttribute.Style, "width:100%", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Table);
  writer.RenderBeginTag(HtmlTextWriterTag.Tr);
  writer.AddAttribute(HtmlTextWriterAttribute.Style, "width:" + Indent.ToString().Trim() + "%", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Td);      //indent
  writer.RenderEndTag();                            //indent td
  writer.AddAttribute(HtmlTextWriterAttribute.Style, "width:" + LabelWidth.ToString().Trim() + "%", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Td);      //label
  lbl.RenderControl(writer);
  writer.RenderEndTag();                            //label td
  writer.AddAttribute(HtmlTextWriterAttribute.Style, "width:" + TextWidth.ToString().Trim() + "%", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Td);      //textbox
  txt.RenderControl(writer);
  writer.RenderEndTag();                            //textbox td
  writer.AddAttribute(HtmlTextWriterAttribute.Style,
    "width:" + (100 - (Indent + LabelWidth + TextWidth)).ToString().Trim() + "%", false);
  writer.RenderBeginTag(HtmlTextWriterTag.Td);      //leftovers
  _astrx.RenderControl(writer);
  writer.RenderEndTag();                            //leftovers td
  writer.RenderEndTag();                            //</tr>
  writer.RenderEndTag();                            //</table>
  writer.RenderEndTag();                            //</div>
}