原帖地址:http://www.cnblogs.com/caviare/archive/2007/09/21/901500.html
另外关于UpdateProgress和Timer控件的使用,可以参考http://read.newbooks.com.cn/info/168590.html
UpdatePanel
对于UpdatePanel 控件的使用是ASP.NET AJAX Extentions的重要部分。我们收到了关于它和UpdateProgress 控件的大量用户反馈。为了增强局部刷新的功能我们作了多处修改,并加强了UpdatePanel 对于控件的兼容性。我们也为异步PoskBack实现了一个丰富的事件模型,这样您就可以在客户端响应它们并对页面更新提供额外操作了。
ScriptManager Control
在RTM版本中,ScriptManager 有一个EnablePartialRendering 属性,其默认值为true ,这减少了使用UpdatePanel 来做异步的页面局部刷新所需的步骤。
为了降低控件的复杂程度,ScriptManager 的ErrorTemplate 属性在RTM版本中被去除了。现在错误处理的模型变得更加灵活,例如您可以为它创建一个独立的服务器控件。另外,您现在也可以使用ScriptManager 的AsyncPostBackErrorMessage 属性,不过它只是设置了默认的错误信息,如果您需要动态地自定义的错误信息的话,您可以使用AsyncPostBackError 事件。
现在ScriptManager 暴露出了一个新的属性AsyncPostBackTimeout ,以此控制异步PostBack的超时时间。
值得一提的是,服务器控件目前可能会使用到ScriptManager 中新增的注册方法。这个方法增加了对于UpdatePanel 使用的支持,并减少了CTP版本中UpdatePanel 的复杂性。现在的资源已经包括了脚本,样式表,Hidden Field等。ClientScriptManager 中的方法与上述方法相对应。它们能够接受一个控件实例作为参数,这样如果在UpdatePanel 中使用这些控件,他们所需的脚本就能被正确跟踪了。
Dynamic UpdatePanel Controls
现在有两种在页面中动态添加UpdatePanel 的方法,这是RTM版本中最大的改进。使用动态UpdatePanel 的方法是:
- 编写自定义控件的开发人员现在能够将UpdatePanel 控件添加到组合控件中。这样,只要页面中存在ScriptManager 并且其EnablePartialRendering 设为true ,这样就能使用该自定义控件并得到局部刷新的体验了。并且,如果页面中没有ScriptManager ,也能在传统PostBack模型中正常使用该控件。
- 页面开发人员能够在其他控件的模版中添加UpdatePanel 。
base .CreateChildControls();
ScriptManager sm = ScriptManager.GetCurrent(Page);
Control parent;
Control container;
if (sm == null || ! sm.EnablePartialRendering) {
// If not doing partial rendering, use a
// dummy control as the container.
parent = container = new Control();
}
else {
// Create an UpdatePanel control.
UpdatePanel up = new UpdatePanel();
// Instead of adding child controls directly to
// the UpdatePanel control, add them to its
// ContentTemplateContainer.
container = up.ContentTemplateContainer;
parent = up;
}
AddDataControls(container);
Controls.Add(parent);
}
Client Events During Asynchronous Postbacks
在CTP版本中,客户端 PageRequestManager 对象依靠 XMLHttpRequest 对象来实现异步的PoskBack并处理 Response 。在RTM版本中, PageRequestManager 对象提供了一个异步PoskBack的生命周期事件,您能够使用它们自定义处理Request和Response的方式。以下为可用的客户端事件,并且提供了事件所需的参数信息:
- initializeRequest :您能够使用这个事件来取消即将发送的异步PostBack请求,它也能够让您根据PostBack信息来做一些额外的工作。这个事件的参数为InitializeRequestEventArgs 类型。
- beginRequest :您能够使用该事件来启动某些工作,例如您可以在这个事件中显示Progress并且在endRequest 事件中再将其隐藏。这个事件的参数为BeginRequestEventArgs 。
- pageLoding :您能够使用这个事件中为UpdatePanel 的即将更新或删除进行一些额外的工作,例如释放资源。您也可以在响应这个事件时检查服务器端发送过来的自定义信息,以此进行一些自定义工作。这个事件的参数为PageLoadingEventArgs 类型。
- pageLoaded :这个事件和pageLoading 事件相似,它提供了异步PostBack结果所创建的UpdatePanel 的信息。这个事件的参数为PageLoadedEventArgs 类型。
- engRequest :您能够使用这个事件来自定义错误处理方式,处理服务器端发送的额外信息等工作。您可以使用它来隐藏UpdateProgress 控件。这个事件的参数为EndRequestEventArgs 类型。
Developing Controls Compatible with the UpdatePanel Control
在CTP版本中, UpdatePanel 控件会处理许多被输出的对象,甚至包括不在 UpdatePanel 中的控件,然后在页面上进行完整的更新。这使一些控件无法和 UpdatePanel 兼容了。例如,在CTP版本中,如果在 UpdatePanel 动态添加ASP.NET验证控件的话,它们便无法正确工作了,这种情形在使用 Wizard 控件的每一步中验证用户输入时尤为常见。
在RTM版本中改变了 UpdatePanel 的模型。您可以使用注册脚本类库相同的办法,向 ScriptManager 注册将要发送到客户端的脚本或数据。在RTM版本中包括了一组新的ASP.NET验证控件,它们会将自己的脚本使用 ScriptManager 注册。这些新控件的Tag名与ASP.NET原有的验证控件相对应,因此您不需要改变在页面中声明创建的验证控件。不过,如果在 UpdatePanel 内部使用了验证控件的话,您需要改变代码以使用新的控件。
下面的示例展示了RTM版本中的一个兼容 UpdatePanel 的自定义控件。如下:
base .OnPreRender(e);
Control control = FindControl(_controlID);
// Register scripts with new ScriptManager APIs.
// The scripts hook up new PageRequestManager events.
string script = String.Format(
CultureInfo.InvariantCulture,
@" var {0}_hover =
new Microsoft.Samples.HoverExtender(document.getElementById('{1}'), '{2}');
{0}_hover.attach(); " ,
ClientID,
control.ClientID,
ColorTranslator.ToHtml(BackgroundColor));
ScriptManager.RegisterClientScriptInclude(
this , typeof (HoverExtender), " HoverExtenderScript " ,
ResolveClientUrl( " ~/ScriptLibrary/HoverExtender.js " ));
ScriptManager.RegisterStartupScript(
this , typeof (HoverExtender), ClientID, script, true );
}
Sending Additional Data to the Client
在CTP版本中,有个功能比较难以实现,那就是在异步PoskBack页面后,根据从服务器端收到的数据更新UpdatePanel外的控件。在RTM版本中可以通过调用ScriptManager的一个方法将数据注册并输出到页面,以此解决这个问题。
试想,如果需要使用服务器的代码来改变客户端的Timer控件的interval和enabled属性的值,但是这个Timer却不在UpdatePanel中。在CTP版本中是无法做到这一点的。
在RTM版本中, ScriptManager 在服务器段保存了一个字典对象,您可以使用 RegisterDataItem 方法来更新和注册对象。这个字典会被发送到客户端,您可以在客户端的 pageLoading , pageLoaded 和 endRequest 事件中通过 eventArgs.get_dataItems() 方法获得该字典对象。
下面的示例展示了注册数据的方法:
...
public int interval {
get {...}
set {
_data = value;
...
}
}
void PreRender() {
ScriptManager sm1 = ScriptManager.GetCurrent(Page);
if (sm1 != null && sm1.IsInAsyncPostBack) {
ScriptManager.RegisterDataItem( this , _data.ToString());
}
// The control also needs to register script to handle the
// endRequest event on the client and retrieve this value.
// The script below adds a handler for the current instance
// of the PageRequestManager object and calls the
// get_dataItem() method from eventArgs.
ScriptManager.RegisterClientScriptBlock( this , this .GetType(), key, script)
}
Custom Error Handling and Redirection
在CTP版本中并没有提供控制错误的办法,甚至没有自定义错误的设置。在RTM版本中则解决了这个问题。
在 ScriptManager 对象里提供了一个属性: AllowCustomError 。当该属性被设为 false 时, ScriptManager 对象会覆盖自定义的错误跳转,并将错误信息发送到客户端,这样您就可以将错误信息显示出来,而避免了页面被转向到其他地方。
在RTM版本中是通过一个额外的 Redirct Module来控制页面转向的。因此,在RTM版本中已经能够处理跨页面的Posting的情况。
Triggers
在CTP版本中, ScriptManager 控件使用了 ControlValueTrigger 和 ControlEventTrigger 类型,并将它们存放一个触发器集合中,以此将这些触发器绑定到页面的控件上去。在RTM版本中,两者被集中到了一个类型: AsyncPostBackTrigger ,以此避免以前的两个触发器可能带来的混乱状况。
根据用户反馈,我们增加了一个 PostBackTrigger 对象,它提供了了从 UpdatePanel 内部产生页面完全(同步)PostBack的能力。这个 Trigger 对象现在也能够与实现了 IPostbackEventHandler , IPostbackDataHandler 或者 INamingContainer 接口的控件配合使用。
AsyncPostBackTrigger 能够使 UpdatePanel 触发异步的PostBack更新。这个触发器也能指向 UpdatePanel 外部的控件,或者指向控件的层次结构中的父控件。当一个作为naming container的控件被指定为触发器,则它内部的所有控件所引发的PoskBack都和这个触发器的行为相同。
下面的例子展示了 AsyncPostBackTrigger 对象声明形式的使用方法:
< asp:UpdatePanel ID ="UP1" UpdateMode ="Conditional" runat ="server" >
< ContentTemplate >... </ ContentTemplate >
< Triggers >
< asp:AsyncPostBackTrigger ControlID ="Button1" />
</ Triggers >
</ asp:UpdatePanel >
一个 PostBackTrigger 能够指向一个 UpdatePanel 内部的控件,使它能产生普通的PostBack。这些控件必须是当前UpdatePanel内部的控件。
UpdateProgress Control
在RTM版本中增强了 UpdateProgress 控件,使它具有了一个额外的功能:指定一个时间间隔,只有异步PostBack超出这个时间后才显示Progress控件。您也可以控制UpdateProgress的输出来控制这个控件在隐藏时是否会占用页面的空间,就像设置ASP.NET验证控件的 DisplayMode 属性一样。另外,您还可以通过增加几行代码,为Progress UI添加一个取消的功能。
下面的例子展示了如何设置 UpdateProgress 控件,使它只在PostBack超过半秒(500毫秒)之后才显示出来:
<ProgressTemplate>
<b>Working on request...</b>
<input type="button" id="abortButton" οnclick="abortPB()" value="Cancel" />
</ProgressTemplate>
</asp:UpdateProgress>
<script type="text/javascript">
function abortPB() {
var obj = Sys.WebForms.PageRequestManager.getInstance();
if (obj.get_isInAsyncPostBack()) {
obj.abortPostBack();
}
}
</script>