当前位置: 首页 > news >正文

Master Page 的原理分析, IParserAccessor.AddParsedSubObject 方法

当一个 ASP.NET 页面的请求发生时,Page 对象初始化的次序是
constructor -> AddParsedSubObject -> ...
可见 AddParsedSubObject 这个方法会较早被调用。

System.Web.UI.Control 类实现了 IParserAccessor 接口,
它对此接口实现如下:(通过 Reflector 看到的)
None.gif void  IParserAccessor.AddParsedSubObject( object  obj)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      
this.AddParsedSubObject(obj);
ExpandedBlockEnd.gif}

None.gif 
None.gif
protected   virtual   void  AddParsedSubObject( object  obj)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      Control control1 
= obj as Control;
InBlock.gif      
if (control1 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            
this.Controls.Add(control1);
ExpandedSubBlockEnd.gif      }

ExpandedBlockEnd.gif}

None.gif 
None.gif

我们可以看到 Control 类给 AddParsedSubObject 方法提供了一个默认实现,默认的行为就是简单的判断如果该对象存在则添加到自己的子控件集合中去。
同时他设定访问性级别为 virtual,给继承自他的子类(我们要编写的自定义控件)以重写该方法的实现的机会。
在某些高级的页面模版解决方案中,通常覆盖这个方法,把分析出来的页面的控件添加到某个特定的页面模版中去。

Paul Wilson 的 MasterPage 控件里这个部分是这样写的:
ExpandedBlockStart.gif ContractedBlock.gif protected   override   void  AddParsedSubObject( object  obj)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (obj is Wilson.MasterPages.ContentRegion) dot.gif{
InBlock.gif        
this.contents.Add(obj);
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gifContractedSubBlock.gif    
else dot.gif{
InBlock.gif        
this.defaults.Controls.Add((Control)obj);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

下面看一下 msdn 对该接口的解释。

IParserAccessor 接口只规定了一个方法:
None.gif void  AddParsedSubObject( object  obj);

这个方法的目的是:( 中文 msdn 这个方法的翻译很烂,郁闷了很久之后翻看原文的才看懂了)。

通知服务器控件,它的一个元素(XML 或 HTML) 已经分析完毕了;并且把这个元素添加到服务器控件的 ControlCollection 对象中去。

参数 obj: 已分析的 Object.

注:
除非你覆盖它,这个方法会自动的向控件的 ControlCollection 集合(通过 Control.Controls 来访问)添加一些 LiteralControl.(实际上是 tag 间隔处的空白)。

msdn 例子:
这个代码演示了如何把自定义的子 tag  (例子中叫做 "myitem") 当作 TextBox 来处理。
None.gif //  Custom ControlBuilder class. Interprets nested tag name "myitem" as a textbox. 
None.gif
public   class  MyControlBuilder : ControlBuilder 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
public override Type GetChildControlType(String tagName,
InBlock.gif                                       IDictionary attributes)
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
if (String.Compare(tagName, "myitem"true== 0
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         
return typeof(TextBox);
ExpandedSubBlockEnd.gif      }

InBlock.gif      
return null;
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

None.gif
None.gif
None.gifControlBuilderAttribute(
typeof (MyControlBuilder)) 
None.gif]
None.gif
public   class  MyControl : Control
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
// Store all the controls specified as nested tags.
InBlock.gif
   private ArrayList items = new ArrayList();
InBlock.gif   
InBlock.gif   
// This function is internally invoked by IParserAccessor.AddParsedSubObject(Object).
InBlock.gif
   protected override void AddParsedSubObject(Object obj) 
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      
if (obj is TextBox) 
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif         items.Add(obj);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif   }

InBlock.gif
InBlock.gif   
// Override 'CreateChildControls'. 
InBlock.gif
   protected override void CreateChildControls()
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
InBlock.gif      System.Collections.IEnumerator myEnumerator 
= items.GetEnumerator();
InBlock.gif      
while(myEnumerator.MoveNext())
InBlock.gif          
this.Controls.Add((TextBox)myEnumerator.Current);
ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}
    
None.gif

题外话:
刚才不小心搜到 孟子E章在 csdn 文档中心写的一个关于 ASP.NET 1.x 和 2.0 对照的文章,里面提到 IParserAccessor 接口的以及这个方法好像被微软封掉了。以后只能是系统才有权调用了。
虽然说 ASP.NET 2.0 加入了 MasterPage 机制,但这样做搞的 1.1 的代码不兼容了岂不是很霸道?哪位清楚详情的请证实一下这个事情。

参考:
Master Page, Paul Wilson 相关: http://authors.aspalliance.com/paulwilson/Articles/?id=14

转载于:https://www.cnblogs.com/RChen/archive/2005/03/22/123190.html

相关文章:

  • c++中对应java ShutdownHook的退出处理器
  • 2017第5周二杭州印象
  • 自由文化相关网站
  • spark学习10(win下利用Intellij IDEA搭建spark开发环境)
  • 校验软件包
  • 工作心得
  • jquery动态创建表格
  • 针对 .NET 开发人员的存储过程评估(转)
  • CCF201503-3 节日(100分)
  • 利用U盘启动制作GHO镜像
  • 软件测试面试题集锦
  • InfoVista.NET 概述
  • 昨天,今天,明天
  • 敏捷开发思想与实践
  • 上海的芝士蛋糕地图 (zz)
  • @jsonView过滤属性
  • 2017 年终总结 —— 在路上
  • ComponentOne 2017 V2版本正式发布
  • GitUp, 你不可错过的秀外慧中的git工具
  • Gradle 5.0 正式版发布
  • jquery cookie
  • js操作时间(持续更新)
  • JS函数式编程 数组部分风格 ES6版
  • Laravel Mix运行时关于es2015报错解决方案
  • php中curl和soap方式请求服务超时问题
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Spring-boot 启动时碰到的错误
  • spring学习第二天
  • ubuntu 下nginx安装 并支持https协议
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 关于使用markdown的方法(引自CSDN教程)
  • 京东美团研发面经
  • 离散点最小(凸)包围边界查找
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端面试之CSS3新特性
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 微信小程序填坑清单
  • 国内开源镜像站点
  • ​ssh免密码登录设置及问题总结
  • ​什么是bug?bug的源头在哪里?
  • # .NET Framework中使用命名管道进行进程间通信
  • #LLM入门|Prompt#3.3_存储_Memory
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #每天一道面试题# 什么是MySQL的回表查询
  • (02)Hive SQL编译成MapReduce任务的过程
  • (poj1.2.1)1970(筛选法模拟)
  • (转)fock函数详解
  • (转)程序员疫苗:代码注入
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • ***通过什么方式***网吧
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET企业级应用架构设计系列之技术选型
  • .net实现客户区延伸至至非客户区
  • @RequestMapping处理请求异常