博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

UpdatePanel工作原理

Posted on 2011-11-01 21:18  肖敏  阅读(2010)  评论(0)    收藏  举报
  •  UpdatePanel如何实现部分呈现?

      我们知道,使用UpdatePanel向服务器发送一个异步请求,服务器处理该请求,初始化控件树的过程跟处理一般的请求是没有任何区别的。但是为什么最终向客户端呈现的只是UpdatePanel包含的控件内容,而不是整个控件树的内容呢?难道是ScriptManager偷偷的把其他的控件移除了吗?

      答案是否定的。

      ScriptManager控件首先是个普通的控件,在初始化时注册了一个RenderPageCallback函数,该函数在预呈现的时候执行。该函数中有一个关键的语句:

     

      form.SetRenderMethodDelegate(new RenderMethod(this.RenderFormCallback));

      该方法为form控件注册了一个RenderMethod方法RenderFormCallback,该方法就是呈现UpdatePanel里的内容的逻辑。为什么注册了RenderMethod方法就可以让其他的控件不被呈现,关键在于Control的RenderChildrenInternal方法。假如RenderMethod代理不为空,它就不会呈现自己的子控件!!!

     

internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
{
    if ((this.RareFields != null) && (this.RareFields.RenderMethod != null)) //不会呈现自己的子控件
    {
        writer.BeginRender();
        this.RareFields.RenderMethod(writer, this);
        writer.EndRender();
    }
    else if (children != null)
    {
        foreach (Control control in children)
        {
            control.RenderControl(writer);
        }
    }
}

  •  UpdatePanel如何知道页面里没有ScriptManger控件?

     当我们使用UpdatePanel时,如果没有拖一个ScriptManager控件到页面里。将会抛一个异常。UpdatePanel是如何知道的?

     这是因为Page类里有一个Items属性,UpdatePanel在初始化的时候通过使用Page.Items[typeof(ScriptManager)] 获取ScriptManager的实例,如果为空则抛异常。我们可以推断出,ScriptManager在初始化的时候,会有这么一个语句Page.Items[typeof(ScriptManager)] = this。因此,ScriptManager必须放在UpdatePanel前面。同理,如果一个页面里放了两个ScriptManager也会抛出异常,原理也是一样的。

  •   UpdatePanel异步提交表单跟普通的提交有什么区别?

     多两个Key-Value,

     _ASYNCPOST true

     <ScriptMangerId> <UpdatePanelId>|<TriggerControlId>