.net控件开发(五)之 深入理解控件的呈现原理

.net控件开发(五)之 深入理解控件的呈现原理

  首言

ASP.NET控件基本上都是继承Framework 已有三个基类,Control,WebControl,CompositeControl下面我就各个基类的呈现方法
      讲述
Control,WebControl, CompositeControl 各自的呈现过程。
   

第一个: Control 呈现过程。

Control 所继承的控件的输出流程:

在正常的控件呈现输出 ( 就是说不是 ajax 控件里 , ajax 会打乱此图 ) 中,它是一个循环调用的过程,看看下面的图就知道了
 

现在来分析分析其实现过程,在 Render 方法中调用另外一个名为 RenderChildren 的受保护成员,

该方法接收服务器控件内容的 HtmlTextWriter 对象 .

protected   internal   virtual   void  Render(HtmlTextWriter writer)
{
    
this .RenderChildren(writer);
}

protected   internal   virtual   void  RenderChildren(HtmlTextWriter writer)
{
/*
在这里this.occasionalFields中,它实现了OccasionalFields类,此类是一个sealed类,也就是一个不可继承的类,在其类中有一个Controls的public属性,返回的是一个控件集(ControlCollection)
在此处是用于维护其子控件列表的集合容器。

*/

ICollection children 
=  ( this ._occasionalFields  ==   null ?   null  : ((ICollection)  this ._occasionalFields.Controls);

    
this .RenderChildrenInternal(writer, children);
}

 

在此,我们什么时候给了 this._occasionalFields 赋值了呢。赋了什么值呢。当加入到控件树上时(使用了 findControl 查找控件),它会调用一个


private   void  EnsureNamedControlsTable

方法(这个方法在
findControl 中调用)去确保所有控件都被正确加载完成。

然后将其填充在一个控件集中
this .FillNamedControlsTable( this this ._occasionalFields.Controls);,

从这里开始注意了, Ajax 异步回调与正常输出的控件是从这里开始分岐的。
 1 internal   void  RenderChildrenInternal(HtmlTextWriter writer, ICollection children)

 2 {

 3 /*

 4 this.RareFields如果设置这个参数,意谓着以自定义的方式去改写RenderChildern

 5 没有的话,将进行默态的流程对所有的子控件进行处理。

 6

 7 */


 8      if  (( this .RareFields  !=   null &&  ( this .RareFields.RenderMethod  !=   null ))

 9 {

10     /* 调用RenderMethod委托,Asp.net Ajax在使用Control.SetRenderMethodDelegate时,对应的回调函数就是在此时处理的

11 关于ajax的控件程现流程详见:  http://www.cnblogs.com/liuxu-wxy/archive/2007/04/25/727346.html

12

13   */


14         writer.BeginRender();

15          this .RareFields.RenderMethod(writer,  this );

16         writer.EndRender();

17     }


18      else   if  (children  !=   null )

19 {

20   // 如果不设置这个RareFieldsEnsured,会把所有的控件呈现                

21          // 依次调用Control里所有子控件的RenderControl               

22          foreach  (Control control  in  children)

23          {

24             control.RenderControl(writer); // 完成子控件的呈现过程

25         }


26     }


27 }


28

 

接下来就是真正呈现过程的入口方法


// 该方法为入口方法

public   virtual   void  RenderControl(HtmlTextWriter writer)

{

    
this .RenderControl(writer,  this .Adapter);

}





下面这段代码, 这个是一个过渡代码,其中的 this.flags[0x10] 没有搞明白是什么一回事,但不要紧。

它都会去调用
  RenderControlInternal 方法


RenderControlInternal代码段

下面代码。控件是否有相关的呈现适配器,有的话就适配器调用适配器的相关呈现方法
private   void  RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)

{

    
if  (adapter  !=   null )

{  

// 调用相关的适配器方法

        adapter.BeginRender(writer);

        adapter.Render(writer);

        adapter.EndRender(writer);

    }


    
else

    
{

        
this .Render(writer);

    }


}



     理解就是 :
1.
控件开始呈现
2.
控件是否有相关的呈现适配器,有的话就适配器调用适配器的相关呈现方法
3.
呈现子控件
4.
完成控件呈现

 

第二个: WebControl 呈现过程

WebControl: Control 的基础上增加了 Style ,呈现方面就是在 Render(HtmlTextWriter writer) 方法中扩展了三个呈现方法,增加一个属性呈现方法

流程图如下:

伪代码如下:
    

   public   virtual   void  RenderBeginTag(HtmlTextWriter writer)
        
{
            
this .AddAttributesToRender(writer);
            
// 呈现Tag开始标记
        }


        
protected   override   void  Render(HtmlTextWriter writer)
        
{
            
// 重写了Control的Render方法并增加了三个扩展方法
             this .RenderBeginTag(writer);
            
this .RenderContents(writer);
            
this .RenderEndTag(writer);
        }

        
protected   internal   virtual   void  RenderContents(HtmlTextWriter writer)
        
{
            
// 调用Control的呈现
             base .Render(writer);
        }


        
public   virtual   void  RenderEndTag(HtmlTextWriter writer)
        
{
            
// 呈现结束标记
        }


        
protected   virtual   void  AddAttributesToRender(HtmlTextWriter writer)
        
{
            
// 呈现Attribute
        }

 

 

第三个: CompositeControl 呈现过程

   CompositeControl 类是一个抽象类,为自定义控件提供命名容器和控件设计器功能,该自定义控件包含全部子控件或使用其他控件功能。此类由 Login Wizard 等控件继承

复合控件类必须派生自 System.Web.UI.WebControls.CompositeControl 类。这一点与 ASP.NET 1.x 环境下开发复合控件有些不同。在 ASP.NET 1.x 中,复合控件必须实现 System.Web.UI.INamingContainer 接口。然而,在 ASP.NET 2.0 下,复合控件类的基类则发生了变化

public   abstract   class  CompositeControl : WebControl, INamingContainer, ICompositeControlDesignerAccessor
  其余使用以后再讲,今天主要是讲其呈现过程;

CompositeControl 重写了 WebControl Render(HtmlTextWriter writer) ,增加了设计时支持以创建子控件   

 protected  internal  override  void  Render(HtmlTextWriter writer)
        
{
            
// 如果在设计时,创建子控件,也就是在设计时增加友好体验
             if  (DesignMode)
                   
this .EnsureChildControls();
            
base .Render(writer);
        }

————————————————————————————————————

后述:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值