none
Framework 源码提问 在一个aspx页面中 为什么this.Page 和 Repeater.Page 是同一个对象呢? RRS feed

  • 问题

  • 最近研究了下 System.Web.UI 下的源码,发现个问题Page对象也好,其他服务器控件也好,都是继承自Control类,而Control类中有一个Page的属性。可我发现,这些类在页面初始化后,他们的.Page 属性是同一个对象。比如 :
    Page p=this.Page;  Page pForRepeater=Repeater1.Page;  p和pForRepeater 是同一个对象 。这是怎么实现的呢?
    2009年10月21日 1:30

答案

  • 你好!

    Control.Page  是返回的父控件的 Page 对象, Control 最上面的是父控件就是 this

    知识改变命运,奋斗成就人生!
    • 已标记为答案 KeFang Chen 2009年10月22日 2:08
    2009年10月21日 2:16
    版主
  • 在整个页面 有一个控件树,这些控件一级一级的递归最终都会获得一个Page对象就是页面中this


    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://blog.tanging.net
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 2:34
    版主
  • 控件是在一个页面里面的。可以想象成一个最外层的容器.

    都是继承自Control类,如果设置 Control类的Page是谁,那么其他的对象自然也就是指向这个  Control类的Page了

    【孟子E章】
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 5:00
    版主
  • 查看Control.Page属性的源码
    
    [WebSysDescription("Control_Page"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), Bindable(false)]
    public virtual Page Page
    {
        get
        {
            if ((this._page == null) && (this.Parent != null))//如果当前私有字段_page为空且父控件不为空就返回父控件的Page
            {
                this._page = this.Parent.Page;
            }
            return this._page;
        }
        set
        {
            if (this.OwnerControl != null) //如果当前空间所有者不为空,那么抛出异常 也就是无法直接给子控件设置page属性
            {
                throw new InvalidOperationException();
            }
            this._page = value;
        }
    }
    
    当把控件添加到另一个控件的时候就会把 这个控件的Parent设置为添加到的控件
    这样就一级级的传递下来了
    
    而Page类的构造函数中默认会把_page设置为当前实例
    public Page()
    {
        this._maxPageStateFieldLength = DefaultMaxPageStateFieldLength;
        this._enableEventValidation = true;
        base._page = this;
    
     
    

    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://blog.tanging.net
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 15:05
    版主
  • Control类Page属性的获取方法

    public virtual Page Page
    {
        get
        {
            if ((this._page == null) && (this.Parent != null))
            {
                this._page = this.Parent.Page;
            }
            return this._page;
        }
        set
        {
            if (this.OwnerControl != null)
            {
                throw new InvalidOperationException();
            }
            this._page = value;
        }
    }
    从 Trace信息可以看出,Page对象是所有控件的最顶级容器,所以,按照获取Page属性的方法来看,最终会通过Parent来找到 页面的Page对象(一般是当前页面的文件名命名)

    __Page ASP.default12_aspx


    【孟子E章】
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 15:08
    版主

全部回复

  • 你好!

    Control.Page  是返回的父控件的 Page 对象, Control 最上面的是父控件就是 this

    知识改变命运,奋斗成就人生!
    • 已标记为答案 KeFang Chen 2009年10月22日 2:08
    2009年10月21日 2:16
    版主
  • 在整个页面 有一个控件树,这些控件一级一级的递归最终都会获得一个Page对象就是页面中this


    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://blog.tanging.net
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 2:34
    版主
  • 控件是在一个页面里面的。可以想象成一个最外层的容器.

    都是继承自Control类,如果设置 Control类的Page是谁,那么其他的对象自然也就是指向这个  Control类的Page了

    【孟子E章】
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 5:00
    版主
  • 恩 能说的详细点么?Control中有好多方法。请问是在 Control的InitRecursive 方法中赋值的么? 还有就是,虽然是一个类,可是不同的控件等于实例化了多个Control,他们怎么能找到一个公共的连接点呢?这个在Control源码中么?

    2009年10月21日 14:34
  • 恩 能说的详细点么?Control中有好多方法。请问是在 Control的InitRecursive 方法中赋值的么? 还有就是,虽然是一个类,可是不同的控件等于实例化了多个Control,他们怎么能找到一个公共的连接点呢?这个在Control源码中么?

    2009年10月21日 14:39
  • 查看Control.Page属性的源码
    
    [WebSysDescription("Control_Page"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false), Bindable(false)]
    public virtual Page Page
    {
        get
        {
            if ((this._page == null) && (this.Parent != null))//如果当前私有字段_page为空且父控件不为空就返回父控件的Page
            {
                this._page = this.Parent.Page;
            }
            return this._page;
        }
        set
        {
            if (this.OwnerControl != null) //如果当前空间所有者不为空,那么抛出异常 也就是无法直接给子控件设置page属性
            {
                throw new InvalidOperationException();
            }
            this._page = value;
        }
    }
    
    当把控件添加到另一个控件的时候就会把 这个控件的Parent设置为添加到的控件
    这样就一级级的传递下来了
    
    而Page类的构造函数中默认会把_page设置为当前实例
    public Page()
    {
        this._maxPageStateFieldLength = DefaultMaxPageStateFieldLength;
        this._enableEventValidation = true;
        base._page = this;
    
     
    

    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://blog.tanging.net
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 15:05
    版主
  • Control类Page属性的获取方法

    public virtual Page Page
    {
        get
        {
            if ((this._page == null) && (this.Parent != null))
            {
                this._page = this.Parent.Page;
            }
            return this._page;
        }
        set
        {
            if (this.OwnerControl != null)
            {
                throw new InvalidOperationException();
            }
            this._page = value;
        }
    }
    从 Trace信息可以看出,Page对象是所有控件的最顶级容器,所以,按照获取Page属性的方法来看,最终会通过Parent来找到 页面的Page对象(一般是当前页面的文件名命名)

    __Page ASP.default12_aspx


    【孟子E章】
    • 已标记为答案 KeFang Chen 2009年10月22日 2:09
    2009年10月21日 15:08
    版主