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


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

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

     
    protected virtual void AddParsedSubObject(object obj)
    {
          Control control1 
    = obj as Control;
          
    if (control1 != null)
          
    {
                
    this.Controls.Add(control1);
          }

    }

     

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

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

        
    else {
            
    this.defaults.Controls.Add((Control)obj);
        }

    }

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

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

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

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

    参数 obj: 已分析的 Object.

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

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

          
    return null;
       }

    }



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

       }


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

    }
        

    题外话:
    刚才不小心搜到孟子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
    posted on 2005-03-22 01:56 木野狐 阅读(1921) 评论(1)  编辑 收藏 收藏至365Key 所属分类: .NET
    -->

    Feedback

    # re: Master Page 的原理分析, IParserAccessor.AddParsedSubObject 方法 2005-03-22 14:31 木野狐
    AddParsedSubObject 方法的实现, 其实仅仅是把已分析的控件给归归类。如果是模板里预留的一个空位(Slot)那就先存到一个私有的 Slot 数组里等待后续的处理;
    否则的话属于普通的 Control, 那就加到一个默认 Slot 里面去.(default ContentRegion). 该方法里还没有涉及添加哪些控件到自身 Controls 集合里去.

    接下来执行的动作是:
    BuildMasterPage 私有方法.

    该方法完成了模板 Slot 及其预定义默认内容的复制过程.
    先用 LoadControl 方法加载存储模板的那个 UserControl;
    把其中的所有子控件去除掉,同时判断如果是可见的则添加到自身(主页面对象)的 Controls 集合.
    最后把模板 UserControl 本身(一个空壳)加到 Controls 集合的最开始处.

    最后的 BuildContents 私有方法里,
    将主页面里定义的 Slot 的所有实现替代到从模板里复制来的 Slot 里面.(具体实现).
  • 相关阅读:
    fedora中使用 mariadb数据库建库和建表-- mariadb数据库服务无法启动?
    我在linux中使用的vundle 和 vimrc配置
    vim的加密和解密?
    gvim写html代码时如何快速地跳转到一个标签的结束位置: 终极插件: matchit.vim
    HTML5+CSS3整体回顾
    HTML5无刷新修改URL
    使用ab对nginx进行压力测试
    nginx php-fpm 输出php错误日志
    如何正确配置Nginx+PHP
    关于Nginx的一些优化(突破十万并发)
  • 原文地址:https://www.cnblogs.com/cxd4321/p/573947.html
Copyright © 2020-2023  润新知