ASP.NET 自定义控件从入门到精通3补充
ASP.NET 自定义控件从入门到精通
3 状态管理和Style类
3.2 新的Render方法
首先我们来看看Register控件在前台生成的Html代码,代码如下所示:
<!—注意这是开始标记 -->
<table>
<!—注意这是Caption标记 -->
<caption>用户注册</caption>
<!—注意这才是存储控件tbody标记 -->
<tbody>
<tr>
<td>用户名:</td>
<td> <input name='txtUserName' type='text' id='txtUserName' value='请输入用户名' onfocus='this.select()' /> </td>
</tr>
<tr>
<td>密 码:</td>
<td> <input name='txtPassword' type='password' id='txtPassword' value='' /> </td>
</tr>
<tr>
<td>确认密码:</td>
<td> <input name='txtSecPassword' type='password' id='txtSecPassword' /> </td>
</tr>
<tr>
<td colspan='2'>
<input type='submit' name='btnRegister' value='注册' id='btnRegister' />
<input type='reset' id='btnReset' value='重置' />
</td>
</tr>
</tbody>
<!—注意这是结束标记 -->
</table>
我们可以清楚的看到一个注册控件被分为4各部分,那么我们应该将生成这4段的代码的方法拆分为4个方法。
现在我们修改Render方法,使用HttpTextWriter的样式定制Register控件。代码如下所示:
[DefaultProperty("UserName")]
[ToolboxData("<{0}:RegisterControl runat='server' UserName='请输入用户名' />")]
public class RegisterControl : WebControl
{
public RegisterControl() : base()
{
this.UserName = string.Empty;
this.UserPwd = string.Empty;
}
[Browsable(true)]
[Description("读写属性,获取或设定用户名密码框中的值")]
[Category("杂项")]
public virtual string UserPwd
{
get { return this.ViewState["UserPwd"].ToString(); }
set { this.ViewState["UserPwd"] = value; }
}
[Browsable(true)]
[Description("读写属性,获取或设定用户名文本框中的值")]
[DefaultValue("请输入用户名")]
[Category("杂项")]
public virtual string UserName
{
get { return this.ViewState["UserName"].ToString(); }
set { this.ViewState["UserName"] = value; }
}
protected override void Render(HtmlTextWriter writer)
{
//writer.Write(string.Format(@" <table> <caption>用户注册</caption> <tbody> <tr> <td>用户名:</td> <td> <input name='txtUserName' type='text' id='txtUserName' value='{0}' onfocus='this.select()' /> </td> </tr> <tr> <td>密 码:</td> <td> <input name='txtPassword' type='password' id='txtPassword' value='{1}' /> </td> </tr> <tr> <td>确认密码:</td> <td> <input name='txtSecPassword' type='password' id='txtSecPassword' /> </td> </tr> <tr> <td colspan='2'> <input type='submit' name='btnRegister' value='注册' id='btnRegister' /> <input type='reset' id='btnReset' value='重置' /> </td> </tr> </tbody> </table> ",this.UserName,this.UserPwd));
this.RenderBeginTag(writer);
this.RenderCaptionTag(writer);
this.RenderTbodyTag(writer);
this.RenderEndTag(writer);
}
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.AddAttribute(HtmlTextWriterAttribute.Id,"RegisterTable");
writer.AddStyleAttribute(HtmlTextWriterStyle.Width,"auto");
writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "auto");
}
protected void RenderCaptionTag(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Caption);
writer.Write("用户注册");
writer.RenderEndTag();
}
protected void RenderTbodyTag(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Tbody);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("用户名");
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(string.Format("<input name='txtUserName' type='text' id='txtUserName' value='{0}' onfocus='this.select()' />",this.UserName));
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("密码");
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(string.Format(" <input name='txtPwd' type='Password' id='txtPWd' value='{0}' />",this.UserPwd));
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("确认密码");
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(" <input name='txtSecPwd' type='Password' id='txtSecPwd' />");
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "center");
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Colspan,"2");
writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign,"center");
writer.Write(" <input name='btnRegister' type='submit' id='btnRegister' value='提交' />");
writer.Write(" ");
writer.Write(" <input name='btnReset' type='reset' id='btnReset' value='重置' />");
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
public override void RenderEndTag(HtmlTextWriter writer)
{
writer.RenderEndTag();
}
}
仔细阅读以上代码,发现我们的现在RenderControl控件的Render()方法已经发生了很大的变化。本节中的修改主要是为了日后的做铺垫。
3.2 Style类
对于自定义控件而言,外观定制一直以来困扰很多开发者。我们可以在Reander()方法中通过字符串设定控件的基本样式,但是字符串非常容易出错,并且没有良好的复用性。
在ASP.NET中提供了Style类用于控制控件外观,使用Style类有以下一些好处:
- 公开CSS样式属性为强类型属性,可以很容易的获取编译器的支持,减少出错的可能。
- 可以使用强类型属性映射至CSS样式属性,如BorderWidth属性必须使用短整形赋值,可以很好的杜绝字符串带来的异常。
Style类公开了一些基本的CSS样式属性,如表3.2所示:
表3.2 Style属性公开的基本CSS样式属性
属性 | 说明 |
BackColor | Color类型的属性,读写属性,设定控件的背景色。 |
BorderColor | Color类型的属性,读写属性,设定控件的边框色。 |
BorderStyle | BorderStyle类型的属性,读写属性,BorderStyle类本身就是Style类的子类用于设定控件的边框样式。 |
BorderWidth | UInt类型的属性,读写属性,设定控件的边框宽度。 |
CssClass | 字符串类型的属性,读写属性,设定控件的客户端CSS类选择器名称。 |
Font | FontInfo类型的属性,读写属性,设定控件字体。 |
ForeColor | Color类型的属性,读写属性,设定控件字体颜色。 |
Height | Uint类型的属性,读写属性,设定控件高度。 |
Width | Uint类型的属性,读写属性,设定控件宽度。 |
大家请注意,Style类并没有提供完全的Css样式属性的控制,Stye类还拥有很多子类用于控制特定Html元素或CSS中的样式。
下一节将展示使用自定义Style类以及自定义外观的使用。