自定义控件开发:开发简单的自定义控件

我们知道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=form1>

    <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>Cardholders Name</strong></td><td><input type=text /></td>

        </tr>

        <tr>

            <td><strong>Expiration Date</strong></td>

            <td>

                <select>

                <option value=1>01</option>

                ...

                </select>&nbsp;

                <select>

                <option value=2005>2005</option>

                ...

                </select>

            </td>

        </tr>

        <tr>

            <td colspan=2 align=center><input type=submit value=Submit /></td>

        </tr>

    </table>

</form>

</body>

</html>

接下来我们将学习如何把包含在上面Form中的HTML代码用一个服务器端控件生成,这个控件就是我们将要自定义的CreditCardForm1。我们的目标是用如下的一段ASPX代码生成与“代码 2-1”同样的HTML

代码 2-2

<html xmlns=http://www.w3.org/1999/xhtml >

<head><title>Untitled Page</title></head>

<body>

    <form id=form1 runat=server>

        <custom:CreditCardForm1 runat=server ID=ccf />

    </form>

</body>

</html>

控件CreditCardForm1可以看做一个容器,它封装了“代码 2-1中的HTMLCreditCardForm1自定义控件从ASP.NET的基类Control继承而来。所有服务器控件直接或间接从Control基类继承而来,事实上继承于Control基类才使一个服务器控件成为服务器控件。

 

Control基类为服务器控件提供了操作数据的基础架构。其中一个基类方法叫做Render,这个方法正是服务器控件生成HTML的地方。

 

运行时,容器页(.aspx页)创建一个HrmlTextWriter类实例并把该对象传递给该容器页中的服务器控件的Render方法。HrmlTextWriter类有一个Write方法,那些容器页中的服务器控件就可以使用各自的Write方法生成HRML标记了。“代码 2-3包含CreditCardForm1控件的Render方法实现。该方法的实现很简单,它一行一行的把“代码 2-1展示HTML代码传给HtmlTextWriterWrite方法然后输出。

 

举例,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上。现在你看到实现一个简单的自定义控件并没有什么神奇的地方,不是吗?

1,   写下你想要生成的HTML(如“代码 2-1)。

2,   写一个继承自Conrol基类的类。

3,   重写Render方法把HTML一行一行的传递给HtmlTextWriterWrite方法。

代码 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("&nbsp");

      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类的每一个子类被设计为往特定的储存书写文本流。例如,StringWriterStreamWriter子类可以分别向StringStream书写文本流。事实上作为TextWriter抽象类的子类HtmlTextWriter类是专为往服务器控件的输出流中写入HTML标记而设计的。

posted @   leeolevis  阅读(214)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示