我正在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
}
}
任何人都可以指出问题是,还是给我一个解决方案或解决方案片段?我还没有在网上找到一个有用的例子。
答案 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>
}