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

简介:   或许大家还对为何要重写Render方法存有疑惑,希望大家看看我举的例子,能够明白Render方法和其他两个方法的作用,然后真正明白为何一般情况下只须重写Render方法。我们知道我们每次编写控件时,都需要重写Render方法,我们发现在Control类中很多方法可以重写,但我们没有去重写他们,我...

  或许大家还对为何要重写Render方法存有疑惑,希望大家看看我举的例子,能够明白Render方法和其他两个方法的作用,然后真正明白为何一般情况下只须重写Render方法。我们知道我们每次编写控件时,都需要重写Render方法,我们发现在Control类中很多方法可以重写,但我们没有去重写他们,我们需要遵循一个原则,在需要重载的时候再去重写他们
  我们还是先来看看与Render方法相关的两个方法

 
  
// RenderControl方法的基本实现
public void RenderControl(HtmlTextWriter writer)
{
if (Visible)
{
Render(writer);
}
}
// Render方法基本实现
protected virtual void Render(HtmlTextWriter writer)
{
RenderChildren(writer);
}
// RenderChildren方式基本实现
protected virtual void RenderChildren(HtmlTextWriter writer)
{
foreach (Control c in Controls)
{
c.RenderControl(writer);
}
}

  相信看过"ASP.NET服务器控件开发技术与实例"这本书的人,肯定看过上面的一段代码.

  假设你不理解上面的流程(我也不一定理解,希望我的思路对你有帮助),我认为有一种很好的方式来理解上面的流程,跟大家分享一下。现在抛开上面的代码,我们来建一个简单的页面,随意的拖几个控件到界面上,注意最后一个三panel控件,如下图

图一
  我们知道,每个控件都有Visible和EnableViewState属性,Visible用来设置控件是否被呈现.

图二
  现在我们把button控件的Visible属性设置为flase,我们看到了我们预期的效果,接着请启用页面跟踪,这个很重要

图三
  在服务器上运行这个页面,大家可以在控件树上看到下面画面

图四
  (1)System.Web.UI.LiteralControl
  大家可以看到,在我们定义的每个控件之间都有System.Web.UI.LiteralControl。 这里需要说明的是,要理解任何不需要在服务器上处理的任何其他字符串。如何理解呢?大家打开这个运行页面的源代码页面,如下代码,大家看到没有,除了服务器控件外,我们有其他元素(不需要在服务器上处理的任何其他字符串),包括空格。
示例一

 
  
<! 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 = " Default1.aspx " id = " form1 " >
< div >
< input type = " hidden " name = " __VIEWSTATE " id = " __VIEWSTATE " value = " /wEPDwULLTExNTUxMDYxODdkZHVaWm47e5anDettRKviGvS0nDWQ " />
</ div >

< div >
< span id = " Label1 " > Label </ span >< br />
< br />
< input name = " TextBox1 " type = " text " id = " TextBox1 " />< br />
< br />
< br />
< br />
< div id = " Panel1 " style = " height:50px;width:125px; " >


</ div >
& nbsp; </ div >

< div >

< input type = " hidden " name = " __EVENTVALIDATION " id = " __EVENTVALIDATION " value = " /wEWAgK/5/fTBwLs0bLrBrVw7YrSp5G/l4sJGPkKN/asFj2W " />
</ div ></ form >
</ body >
</ html >

  为了让大家更加明白System.Web.UI.LiteralControl的意思的,让我们来修改HTML页面,说明:以上代码为运行后的HTML源代码.而不是我们所说的源代码,大家应该明白我所指的源代码的意思。我们来修改代码,注意:我把<form..以下的标签无空格的写在了一起.看下面修改后的代码

示例二

  运行效果

图五

  现在发现控件之间已经没有System.Web.UI.LiteralControl了,因为我去掉了空格.这个也说明了一点,如果代码很乱的话会影响速度.现在大家应该明白System.Web.UI.LiteralControl的意思了吧.

  (2)大家继续看图四的Button1,大家会发现它呈现的大小字节数为0,因为我们设置了Button1的Visible值为False,所以未呈现此控件.
  下面我们来理解这一点,大家重新看到RenderControl方法,如果Visible值为True则呈现此控件.

if (Visible)
 Render(writer);

  为了理解这个方法,我们来重写此方法,我们以第一次讲的CreditCardForm3控件为例。我们重写RenderControl方法,把Render方法的代码全部拷贝到RenderControl方法中,然后去掉Render方法。然后在asp.net页面使用此控件,定义其Visible值为False

图六
  运行这个例子以后,你会发现控件还是呈现了,就是因为你重写了RenderControl方法,使控件的Visible值无效了,所以我们就要加上一个判断

if (Visible)  {}

  否则的话,此方法呈现的内容没有Visible值.为了更加深刻理解这一点,我们重写基类的RenderControl方法的方法.

base .RenderControl(writer);

  你会发现在页面呈现时的控件有两个,一个在RenderControl方法方法输出,一个在Render方法输出,因为base.RenderControl方法调用了Render方法,当设置控件Visible属性为False时,Render方法输出的内容被隐藏(未被呈现,而RenderControl方法输出的内容仍然存在.现在大家应该了解RenderControl方法的作用了吧.

  如果服务器控件的 Visible 属性设置为 true,则向页呈现服务器控件的内容,所以一般情况下我们不重写此方法.因为一般控件都需要Visible 属性,除非特殊情况.

图七
  (3)RenderChildren方法

  再重新看到图四,大家可以看到,我们拖放的控件是在属于form1的子控件,panel控件是一个容器控件,因为下面没拖放控件,任何其他显示的字符串表现为System.Web.UI.LiteralControl,大家可以拖几个控件到panel里再重新运行看看,会发现拖进去的控件变为panel的子控件.最明显的的测试方法是Wizard控件,拖放一个Wizard控件然后再测试你就会明白了.

  RenderChildren方法则判断当前控件是否有子控件,如果有,则根据RenderControl方法判断控件的Visible值来呈现控件.所以大家在重写Render方法时,不重写基类Render方法时,将无法实现RenderChildren方法.带来的后果将是无法呈现子控件.

  下面我们来测试一下.我们还是以CreditCardForm3控件为例子(请先把RenderControl方法的内容全注释掉),当未重实现RenderChildren方法时则无法呈现子控件内容,请启动跟踪。将发现其子控件呈现字节为0

图八
  由于CreditCardForm3继承了CreditCardForm2,所以重写基类Render方法将会重复输出,我们可以直接在Render方法中重写RenderChildren方法.再来测试.将会发现有些变化,发现其子控件呈现字节并非为0,而是10

图九
  说明其子控件还是存在东西的,只不过没有用而已,所以大家可以根据实际需求来确实是否要重写RenderChildren方法,一般的话都会重写Render方法,这样保险一点。好了,现在再来回顾下刚开始给出的代码,通过上面的试验,你是否明白了?呈现控件的步骤(注意:下面三个方法都可以呈现,不过我们已经说过了,像在RenderControl方法用HtmlTextWriter预先输出的话,就丧失Visible的功能(说不定你就不需要这个功能,那时你就可以重写这个方法了)

  (1)RenderControl方法

  先判断其Visible然后调用Render方法
  (2) Render方法
  使用HtmlTextWriter将标记字符和文本输出然后调用RenderChildren方法
  (3)RenderChildren方法
  判断当前控件是否有子控件,然后再调用RenderControl方法根据子控件的Visible值输出子控件。

  我们了解上面三个方法后,就会知道,一般情况下,我们无须重写RenderControl方法和RenderChildren方法.所以最合适的就是重写Render方法了.说了一大堆.目的就是为了说明为什么要重写Render方法.

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

下一篇:asp.net控件开发基础(3)
目录
相关文章
|
9月前
|
开发框架 JavaScript 前端开发
震撼!破解 ASP.NET 服务器控件 Button 执行顺序之谜,颠覆你的开发认知!
【8月更文挑战第16天】在ASP.NET开发中,通过Button控件实现先执行JavaScript再触后台处理的需求十分常见。例如,在用户点击按钮前需前端验证或提示,确保操作无误后再传递数据至后台深度处理。此过程可通过设置Button的`OnClientClick`属性调用自定义JavaScript函数完成验证;若验证通过,则继续触发后台事件。此外,结合jQuery也能达到相同效果,利用`__doPostBack`手动触发服务器端事件。这种方式增强了应用的交互性和用户体验。
88 8
|
8月前
|
开发框架 前端开发 .NET
VB.NET中如何利用ASP.NET进行Web开发
在VB.NET中利用ASP.NET进行Web开发是一个常见的做法,特别是在需要构建动态、交互式Web应用程序时。ASP.NET是一个由微软开发的开源Web应用程序框架,它允许开发者使用多种编程语言(包括VB.NET)来创建Web应用程序。
195 6
|
8月前
|
开发框架 JavaScript 前端开发
|
9月前
|
开发框架 JSON .NET
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
123 1
|
10月前
|
开发框架 搜索推荐 前端开发
【.NET全栈】ASP.NET开发Web应用——Web部件技术
【.NET全栈】ASP.NET开发Web应用——Web部件技术
|
9月前
|
开发框架 .NET 开发工具
【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?
【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?
|
9月前
|
开发框架 .NET 数据库连接
ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?
ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?
133 0
|
.NET
一起谈.NET技术,ASP.NET 4.0 一些隐性的扩展
  ASP.NET 4.0在很多方面都做了改进,在这篇ASP.NET 4.0白皮书就描述了很多ASP.NET 4.0的机制改变和改进。在我的博客中,也有几篇关于ASP.NET4.0的特性修改的文章。但是作为一个全新的框架和运行时,内部肯定还会有很多API和扩展点不会暴露的那么明显。
867 0
|
Web App开发 .NET 数据库
一起谈.NET技术,ASP.NET中如何正确使用Session
  Asp.Net中的Session要比Asp中的Session灵活和强大很多,同时也复杂很多;看到有一些Asp.Net开发人员报怨说Session不稳定,莫名其妙的丢失,其实这正是Asp.Net改进的地方之一。
1070 0
|
XML 前端开发 .NET
一起谈.NET技术,ASP.NET MVC 2生成动态表单的一种最简单的思路
  在BPM、OA等系统中,都会存在一个表单设计器。有些是通过操作gridview来完成一个表单的设计;有些是通过类似VS拖拽的方法完成一个表单的设计。很明显后面一种优越于前面一种。无论是哪种,最后都会产生一些XML之类的表单结构的数据。
1333 0