一起谈.NET技术,asp.net控件开发基础(4)

简介:   一.从继承WebControl开始  在第二篇教程中,重点介绍了Render()方法的使用,用来呈现控件,但从Control类继承的控件尚未发挥asp.net控件的作用.大家知道web服务器控件分为HTML服务器控件(如这样的形式)和标准服务器控件(就是这样的形式的控件)。

  一.从继承WebControl开始

  在第二篇教程中,重点介绍了Render()方法的使用,用来呈现控件,但从Control类继承的控件尚未发挥asp.net控件的作用.大家知道web服务器控件分为HTML服务器控件(如<input id="Button2" runat="server" type="button" value="button" />这样的形式)和标准服务器控件(就是<asp:..  id="" runat="server" />这样的形式的控件)。

  HTML服务器控件的控件从System.Web.UI.HtmlControls.HtmlControl 类派生,标准服务器控件的控件从System.Web.UI.WebControls.WebControl 类派生,HtmlControl 类和WebControl 类则从System.Web.UI.Control 类派生,并扩展。

  所以我们说,所有的服务器控件都继承自System.Web.UI.Control 类,即所有的服务器控件都具有Control 类的共同属性,如Visible,EnableViewState属性,HtmlControl 类和WebControl 类则扩充了System.Web.UI.Control 类的功能,如HtmlControl 类定义了所有 HTML 服务器控件所通用的方法、属性 (Property) 和事件(具体参数参照MSDN),WebControl 类定义了所有 标准服务器控件所通用的方法、属性 (Property) 和事件(具体参数参照MSDN)。

  如每个继承了WebControl 类的标准控件都有定义外观和行为的属性,然后不同控件再根据需要扩展功能.

  图一

  所以我们推荐的做法是直接从WebControl 类派生,而非Control类.我们所做的非并从头开始.从WebControl 类继承可以帮我们省很多工作.

  二.重写WebControl类方法,不再是Render()

  WebControl类继承了Control类,当然有Render方法,在WebControl类中重写了Render方法,如下代码
  示例一

 
 
protected override void Render(HtmlTextWriter output)
{
 RenderBeginTag(output);
 RenderContents(output);
 RenderEndTag(output);
}

  注意 RebderBeginTag方法并非是HtmlTextWriter类中的方法,而是WebControl类中的方法,表示输出HTML标签头标记,如<table .....>,RenderEndTag方法则输出HTML标签尾标记,如</table>.中间的RenderContents方法则就是Control类的Render方法. 看下面RenderContents方法的定义.
  示例二

 
 
protected override void RenderContents(HtmlTextWriter output){
 
// 使用默认逻辑来呈现子控件,那么一定要调用基类中的方法。
  base .Render(output);
}

  接着再看RenderBeginTag方法的定义
  示例三

 
  
public virtual void RenderBeginTag(HtmlTextWriter output)
{
// 添加呈现控件的属性和样式
// AddAttributesToRender为WebControl类中的方法
AddAttributesToRender(output);
// 呈现控件标签
// 如label控件呈现<span >
// textbox控件呈现<input >
HtmlTextWriterTag tagKey = TagKey;
if (tagKey != HtmlTextWriterTag.Unknown)
{
output.RenderBeginTag(tagKey);
}
else
{
output.RenderBeginTag(
this .TagName);
}
}

  这里打个比方,假设你要输出一个表格,你就必须定义<table>标签头,然后在其内部定义<tr>,<td>,下面看Control类中Render方法的实现,表明Render方法必须完成所有的任务,包括标签头标记<table>和<table>标签的属性和样式的输出.
  示例四

 
  
protected override void Render(HtmlTextWriter writer)
{
// 为table标签定义属性和样式
writer.AddAttribute(HtmlTextWriterAttribute.Width, " 287px " );
writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth,
" 0 " );

writer.RenderBeginTag(HtmlTextWriterTag.Table);


writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(
" <strong> " + PaymentMethodText + " </strong> " );
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Name,
" PaymentMethod " );
writer.AddAttribute(HtmlTextWriterAttribute.Id,
" PaymentMethod " );
writer.AddStyleAttribute(HtmlTextWriterStyle.Width,
" 100% " );
writer.RenderBeginTag(HtmlTextWriterTag.Select);

// 以下代码省略
}

  在WebControl类中重写了Render方法后,直接帮你定义好了标签,默认情况下为<span>,可通过重写TagKey属性来修改标签,然后AddAttributesToRender方法为标签定义样式和属性
  示例五

 
 
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Table; }
}

  示例六

 
  
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
// 为table标签定义属性和样式
writer.AddAttribute(HtmlTextWriterAttribute.Width, " 287px " );
writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth,
" 0 " );

base .AddAttributesToRender(writer);

}

  接着重写RenderContents方法,对比上面的Render方法,实现效果是一样的
  示例七

 
  
protected override void RenderContents(HtmlTextWriter writer)
{
// 注意,此处无没有table标签,只定义其内部标签
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(PaymentMethodText);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.AddAttribute(HtmlTextWriterAttribute.Name, PaymentMethodSelectName);
writer.AddAttribute(HtmlTextWriterAttribute.Id, PaymentMethodSelectId);
writer.AddStyleAttribute(HtmlTextWriterStyle.Width,
" 100% " );
writer.RenderBeginTag(HtmlTextWriterTag.Select);
// 以下省略

}

  所以说重写后的Render方法在默认情况下加了一个标签,而你可以重写这个标签(默认情况下为<span>).可能大家对其感到奇怪,即然可以实现同样效果,有必要重写Render方法,再加一个RenderContents方法吗?
  三.Render方法和RenderContents方法的区别
  当你继承WebControl类,在RenderContents方法中实现示例四代码时,(我们再以以前的例子展示)呈现后的代码如下,看到没有,控件ID为<span>。在RenderContents方法输入的标签将成为其内部标签.再看看这个控件的属性面板,你会看到很多的继承自WebControl类的属性,设置其属性,即是设置<span>标签的属性.TagKey的作用大概就在于此吧,为了使用WebControl类的公共属性,而非定义在<table>标签上。
  示例八

 
 
< span id = " CreditCardForm5_1 " >< table style = " border-width:0; " >
< tr >
< td >< strong > 信用卡类型 </ strong ></ td >< td >< select name = " PaymentMethod " id = " PaymentMethod " style = " width:100%; " >
......

  假设我们称<span>里面的<table>等标签为子标签,在RenderContents方法应该定义控件的子标签,如果你只定义标签属性的话,只需重写AddAttributesToRender方法即可,可不须重写RenderContents方法。
  下面再讲下重写标签的方法

  (1) 重写TagKey属性,下面重写label控件的标签

 
 
public class Ch4Label: Label
{
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Div; }
}
}

  (2)重写基类构造函数,此方法只有在继承Control类后适用

 
 
public CreditCardForm5() : base (HtmlTextWriterTag.Table) { }

   如果控件不复杂,则可直接从标准控件继承(如label),再根据需要扩展,重写AddAttributesToRender方法,还可以重写TagKey更改默认标签,而无须重写RenderContents方法.如果控件比较复杂,不是单一的,则需要在RenderContents方法输出控件的内部的内容。

  其实最大的区别就是默认情况下WebControl类为你加了一个标签,方便添加WebControl类的一些公共的东西,如果你重写Render()方法,而舍弃RenderContents方法,你就无福享受WebControl类给你提供的这么多属性和方法了。

  大家多熟悉下WebControl类的一些公共属性,然后再多改改,可以明白的更加深刻,我喜欢慢慢的把东西全讲全,不然心里不舒服,所以我就慢慢写了,当然前提是我理解的基础上.这次的例子,大家可根据第二篇的代码适当修改就可.错误之处还请指出。

上一篇:asp.net控件开发基础(3)

下一篇:asp.net控件开发基础(5)
目录
相关文章
|
12月前
|
人工智能 芯片
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
|
10月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
425 0
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
247 9
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
218 8
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
210 7
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
502 0
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
299 7
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
397 0
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
297 0
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
316 0