this.Enable = false 会改变控件的CreateChildControls 的调用顺序

CreateChildControls方法来对子控件进行实例化、初始化、并把这些子控件添加到控件树中. createchildcontrols在页生命周期的各个阶段都有可能被执行.首次进入页面时,PreRender方法的默认实现中调用了所有其Visible属性值为true的控件的EnsureChildcontrols方法.而EnsureChildcontrols
会导致CreateChildControls 方法的执行.代码大致如下:

internal virtual void PreRenderRecursiveInternal()
{
    if (!this.Visible)
    {
        this.flags.Set(0x10);
    }
    else
    {
        this.flags.Clear(0x10);
        this.EnsureChildControls();
        if (this._adapter != null)
        {
            this._adapter.OnPreRender(EventArgs.Empty);
        }
        else
        {
            this.OnPreRender(EventArgs.Empty);
        }
        if ((this._occasionalFields != null) && (this._occasionalFields.Controls != null))
        {
            string errorMsg = this._occasionalFields.Controls.SetCollectionReadOnly("Parent_collections_readonly");
            int count = this._occasionalFields.Controls.Count;
            for (int i = 0; i < count; i++)
            {
                this._occasionalFields.Controls[i].PreRenderRecursiveInternal();
            }
            this._occasionalFields.Controls.SetCollectionReadOnly(errorMsg);
        }
    }
    this._controlState = ControlState.PreRendered;
}

 


而页面PostBack后,CreateChildControls也会被调用.在load后,
IPostBackDataHandler.LoadPostData前会被调用,确保子控件都被生成.
而这时候如果控件的 enable = false 那么CreateChildControls依然不会被调用.它还是按照页面第一次加载来调用
下面这句是摘自一个帖子saucer的回复:
 如果你在系统调用CreateChildControls之前设置   Enabled的话,
等CreateChildControls调用base.Controls.Add(box)时,
ViewState会把Enabled的当前值冲掉,所以你需要调用EnsureChildControls(),
确保CreateChildControls被调用

但是我发现如果在PostBack 的时候 最大的问题在于如果 this.Enable = false 的话根本不会在页面的
PostBack后调用控件.这里指的是
在load后,IPostBackDataHandler.LoadPostData前那次调用.而是在PreRenderRecursiveInternal 中再进行调用了,那回传的时候在LoadPostData想访问子控件就不行了.如我在LoadPostData 的时候取子控件的UniqueID为null
了.注:我这是在页面load的时候加载的自定义控件.

还有也页面生命周期的任何一部分调用 findControl() 也会导致EnsureChildcontrols,从而导致CreateChildControls的方法被调用.
posted on 2008-04-19 16:07  kasafuma  阅读(869)  评论(1编辑  收藏  举报