自定义控件开发:开发简单的自定义控件
我们知道ASP.NET中有两种服务器端控件:自定义控件和用户控件。自定义控件必须从基类继承而来,比如Control类。用户控件的实现和实现一个ASP.NET页面差不多,在Visual studio中以所见即所得(WYSIWYG)的形式拖拽而成。
主要内容:
1, 通过继承Control基类实现一个自定义控件,重写它的Render方法。
2, 部署你的自定义控件。
3, 使用你的自定义控件。
4, 为自定义控件添加属性以使控件用户可以自定义他们。
5, 添加特性以使自定义控件可以像ASP.NET自带的控件一样在Visual Studio的设计模式下工作。
6, 把你开发的自定义控件添加到工具箱,现在你可以拖拽使用它们了。
图 2-1
如上图,我们要做的自定义控件由四个Label,三个DropdownList,两个TextBox和一个提交按钮组成。它显示后的HTML代码如下:
代码 2-1:
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head><title>Untitled Page </title></head>
<body>
<form method=”post” action=”Default.aspx” id=”form
<table id=”ccf” style=”font-weight: bold;”>
<tr>
<td><strong>Payment Method</strong></td>
<td>
<select style=”width:100%;”>
<option value=”Visa”>Visa</option>
<option value=”MasterCard”>MasterCard</option>
</select>
</td>
</tr>
<tr>
<td><strong>Credit Card No.</strong></td><td><input type=”text” /></td>
</tr>
<tr>
<td><strong>Cardholder’s Name</strong></td><td><input type=”text” /></td>
</tr>
<tr>
<td><strong>Expiration Date</strong></td>
<td>
<select>
<option value=”
...
</select>
<select>
<option value=”
...
</select>
</td>
</tr>
<tr>
<td colspan=”
</tr>
</table>
</form>
</body>
</html>
接下来我们将学习如何把包含在上面Form中的HTML代码用一个服务器端控件生成,这个控件就是我们将要自定义的CreditCardForm1。我们的目标是用如下的一段ASPX代码生成与“代码 2-1”同样的HTML。
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head><title>Untitled Page</title></head>
<body>
<form id=”form
<custom:CreditCardForm1 runat=”server” ID=”ccf” />
</form>
</body>
</html>
控件CreditCardForm1可以看做一个容器,它封装了“代码 2-
Control基类为服务器控件提供了操作数据的基础架构。其中一个基类方法叫做Render,这个方法正是服务器控件生成HTML的地方。
运行时,容器页(.aspx页)创建一个HrmlTextWriter类实例并把该对象传递给该容器页中的服务器控件的Render方法。HrmlTextWriter类有一个Write方法,那些容器页中的服务器控件就可以使用各自的Write方法生成HRML标记了。“代码 2
举例,HTML的第一行代码是Table元素的开标记和它的属性:
<table id=”ccf” style=”font-weight: bold;”>
只需将这行代码简单的传递给HtmlTextWriter实例的Write方法:
writer.Write("<table style='width:287px;height:124px;border-width:0;'>");
同样的事情只是重复在“代码 2
1, 写下你想要生成的HTML(如“代码 2
2, 写一个继承自Conrol基类的类。
3, 重写Render方法把HTML一行一行的传递给HtmlTextWriter的Write方法。
代码 2-3:
namespace CustomComponents
{
/// <summary>
/// Summary description for CreditCardForm
/// </summary>
public class CreditCardForm1 : Control
{
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<table style='width:287px;height:124px;border-width:0;'>");
writer.Write("<tr>");
writer.Write("<td><strong>Payment Method</strong></td>");
writer.Write("<td>");
writer.Write("<select name='PaymentMethod' id='PaymentMethod' style='width:100%;'>");
writer.Write("<option value='0'>Visa</option>");
writer.Write("<option value='1'>MasterCard</option>");
writer.Write("</select>");
writer.Write("</td>");
writer.Write("</tr>");
writer.Write("<tr>");
writer.Write("<td><strong>Credit Card No.</strong></td>");
writer.Write("<td><input name='CreditCardNo' id='CreditCardNo' type='text' /></td>");
writer.Write("</tr>");
writer.Write("<tr>");
writer.Write("<td><strong>Cardholder's Name</strong></td>");
writer.Write("<td><input name='CardholderName' id='CardholderName' type='text' /></td>");
writer.Write("</tr>");
writer.Write("<tr>");
writer.Write("<td><strong>Expiration Date</strong></td>");
writer.Write("<td>");
writer.Write("<select name='Month' id='Month'>");
for (int day = 1; day < 13; day++)
{
if (day < 10)
writer.Write("<option value='" + day.ToString() + "'>" + "0" + day.ToString() + "</option>");
else
writer.Write("<option value='" + day.ToString() + "'>" + day.ToString() + "</option>");
}
writer.Write("</select>");
writer.Write(" ");
writer.Write("<select name='Year' id='Year'>");
for (int year = 2005; year < 2015; year++)
{
writer.Write("<option value='" + year.ToString() + "'>" + year.ToString() + "</option>");
}
writer.Write("</select>");
writer.Write("</td>");
writer.Write("</tr>");
writer.Write("<tr>");
writer.Write("<td align='center' colspan='2'>");
writer.Write("<input type='submit' value='Submit' />");
writer.Write("</td>");
writer.Write("</tr>");
writer.Write("</table>");
base.Render(writer);
}
}
}
HtmlTextWriter类继承自TextWriter抽象类。TextWriter类的每一个子类被设计为往特定的储存书写文本流。例如,StringWriter和StreamWriter子类可以分别向String和Stream书写文本流。事实上作为TextWriter抽象类的子类HtmlTextWriter类是专为往服务器控件的输出流中写入HTML标记而设计的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现