控件在WEB开发时经常要用到,虽然有部分已经存在工具箱里,但有时总需要根据自己的要求,开发一些合适自己的控件。
服务器控件的开发首先要继承基类,Control,WebControl,CompositeControl,至于这些基类有何特性,大家搜一下。自定义服务器控件的呈现有好几种方法,都是通过Render的方法输出,下面列系Render系列的方法的实现过程。RenderControl,Rednder,RenderBeginTag,RenderContents,RenderEndTag,这几个方法执行的过程是这样,RenderControl会调用Render方法,Render方法再调用RenderBeginTag,RenderContents,RenderEndTag,所以我们在开发的时候直接在RenderBeginTag,RenderContents,RenderEndTag这三个方法里面写代码就可以了。

Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ServerControl
{
public class RenderOutPut : WebControl
{
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("博客园");
}
}
}
这样的控件就以Span输出一个"博客园",你在Default.aspx页面上拖入这个控件,然后运行浏览,查看Html源码:

Code
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
</title></head>
<body>
<form name="form1" method="post" action="default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzc1Nzg5MDYwZGS8eaaFjyrhLWbFGOz9cnFT040a+A==" />
</div>
<span id="CC">博客园</span>
</form>
</body>
</html>
RenderBeginTag与RenderEndTag进行重写的方法输出一个超连接类型的控件,在RenderBeginTag里面定义控件的类型,请看下面代码:

Code
Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ServerControl
{
public class RenderOutPut : WebControl
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Href, "http://www.cnblogs.com"); //通过HtmlTextWriterAttribute添加属性
writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "bule"); //通过HtmlTextWriterStyle添加样式
writer.RenderBeginTag(HtmlTextWriterTag.A); //通过HtmlTextWriterTag添加控件
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("博客园");
}
public override void RenderEndTag(HtmlTextWriter writer)
{
writer.RenderEndTag();
}
}
}
或许你更可以不用那么麻烦,直接在Render里面输出一个控件。

Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ServerControl
{
public class RenderOutPut : WebControl
{
protected override void Render(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Href, "http://www.cnblogs.com");
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.Write("博客园");
writer.RenderEndTag();
}
}
}
直接输出HTML标签也可以实现上面的功能。

Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ServerControl
{
public class RenderOutPut : WebControl
{
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<a href=\"http://www.cnblogs.com\">HTML输出博客园</a>");
}
}
}
还有一种方法就是通过RenderControl方法呈现:

Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace ServerControl
{
public class RenderOutPut : WebControl
{
protected override void Render(HtmlTextWriter writer)
{
HtmlGenericControl A = new HtmlGenericControl("A");
A.Attributes.Add("href", "http://www.cnblogs.com");
A.Style.Add(HtmlTextWriterStyle.Color, "Blue");
A.InnerHtml = "博客园(Render)";
A.RenderControl(writer);
}
}
}
当然RenderControl作为开发服务器控件常用的呈现方法,还有更多的功能,下面给大家介绍一下CreateChildControls与Render结合,输出多个控件组合成的服务器控件

Code
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace ServerControl
{
[DefaultProperty ("TextBoxValue")]
[ToolboxData ("<{0}:RenderOutPut runat=server></{0}:RenderOutPut>")]
public class RenderOutPut : CompositeControl
{
private Label _lblUser;
private Label _lblPassWrod;
private TextBox _txtUser;
private TextBox _txtPassWord;
private Button _bntOK;
private Button _bntReset;
public RenderOutPut()
{ }
/// <summary>
/// 生成控件
/// </summary>
protected override void CreateChildControls()
{
this.Controls.Clear();
_lblUser = new Label();
_lblUser.Text = "用户名: ";
_lblUser.Height = Unit.Pixel(18); //高度与长度的数值你们按自己的意愿去调
_lblUser.ID = "lblUser";
this.Controls.Add(_lblUser);
_lblPassWrod = new Label();
_lblPassWrod.Text = "密 码: ";
_lblPassWrod.Height = Unit.Pixel(18);
_lblPassWrod.ID = "lblPassWrod";
this.Controls.Add(_lblPassWrod);
_txtUser = new TextBox();
_txtUser.Width = Unit.Pixel(100);
_txtUser.Height = Unit.Pixel(18);
_txtUser.ID = "txtUser1";
this.Controls.Add(_txtUser);
_txtPassWord = new TextBox();
_txtPassWord.Width = Unit.Pixel(100);
_txtPassWord.TextMode = TextBoxMode.Password;
_txtPassWord.Height = Unit.Pixel(18);
_txtPassWord.ID = "txtPassWord";
this.Controls.Add(_txtPassWord);
_bntOK = new Button();
_bntOK.Text = " OK ";
_bntOK.ID = "bntOK";
this.Controls.Add(_bntOK);
_bntReset = new Button();
_bntReset.Text = "Reset";
_bntReset.ID = "bntReset";
this.Controls.Add(_bntReset);
this.ChildControlsCreated = true;
}
protected override void RecreateChildControls()
{
if (this.ChildControlsCreated == false)
{
base.RecreateChildControls();
}
}
/// <summary>
/// 输出控件
/// </summary>
/// <param name="writer"></param>
protected override void Render(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, " 0");
writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第一行开始
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("用户注册");
writer.RenderEndTag(); //第一个单元格结束
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("");
writer.RenderEndTag(); //第二个单元格结束
writer.RenderEndTag(); //第一行结束
writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第一行开始
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._lblUser.RenderControl(writer);
writer.RenderEndTag(); //第一个单元格结束
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._txtUser.RenderControl(writer);
writer.RenderEndTag(); //第二个单元格结束
writer.RenderEndTag(); //第一行结束
writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第二行开始
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._lblPassWrod.RenderControl(writer);
writer.RenderEndTag(); //第一个单元格结束
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._txtPassWord.RenderControl(writer);
writer.RenderEndTag(); //第二个单元格结束
writer.RenderEndTag(); //第二行结束
writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第三行开始
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._bntOK.RenderControl(writer);
writer.RenderEndTag(); //第一个单元格结束
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this._bntReset.RenderControl(writer);
writer.RenderEndTag(); //第二个单元格结束
writer.RenderEndTag(); //第三行结束
writer.RenderEndTag(); //结束table
}
}
}
把控件拖进Default.aspx里,运行浏览:

上面的代码继承了INamingContainer接口,想知道什么原因的,你可以在代码中去掉这个继承,运行,查看HTML源代码再认真看一下各控件的ID有什么不同就知道了。
它是以this.NamingContainer.ClientID + "_" + this.ID来命名的。
控件的呈现就介绍到这里了。还有多种不同的方法呈现,这需要大家在开发过程合理运用,是面介绍的只是比较常用的方法而已,实现程序的功能有多种方法,大家按自己的意愿去写吧!欢迎大家讨论,也欢迎大家提出更好的呈现方法。也欢迎大家指正文中的错误。因为每天下班回家做饭,吃完都10点了。都是好晚的时候起草的。
下一章介绍一下怎样设置控件的属性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?