Atlas: ModalUpdateProgress - 模态弹出风格的 UpdateProgress 控件






4.65/5 (39投票s)
2006年10月6日
3分钟阅读

943342

5471
一个以模态弹出窗口样式工作的进度指示器控件。
引言
ASP.NET AJAX 有一个很酷的 UpdateProgress
控件,它在更新一个或多个 UpdatePanel
控件时提供视觉指示。但是,如果当 UpdateProgress
显示时,页面上的所有其他元素都能被禁用,那就更有用了。这促使我构建了 ModalUpdateProgress
控件,其中 UpdateProgress
将充当一个模态弹出窗口。
UpdateProgress 控件的工作原理
如果你使用 Reflector 打开 System.Web.Extensions.dll,你就可以查找 UpdateProgress 控件的工作原理。简单来说,它实现了 IScriptControl
的两个方法 GetScriptDescriptors()
和 GetScriptReferences()
。根据 AJAX 文档,GetScriptDescriptors()
返回一个组件、行为和客户端控件的列表,这些是 UpdateProgress
控件的客户端功能所必需的;而 GetScriptReferences()
返回 UpdateProgress
控件的客户端脚本库依赖项列表。在 GetScriptDescriptors()
中,UpdateProgress
控件注册一个 ScriptControlDescriptor
,其类型名称为 Sys.UI._UpdateProgress
,这是一个在 MicrosoftAjaxWebForms.js 中可用的类(MicrosoftAjaxWebForms.js 是 ASP.NET AJAX 客户端脚本库之一,嵌入在 System.Web.Extensions.dll 中)。通过查看 MicrosoftAjaxWebForms.js 的调试版本,很容易理解 Sys.UI._UpdateProgress
中的逻辑。
构建 ModalUpdateProgress 控件
首先,我们从 UpdateProgress
派生 ModalUpdateProgress
,这样我们就可以重用其现有的属性和接口。然后我们需要重写这两个方法 GetScriptDescriptors()
和 GetScriptReferences()
,并实现客户端脚本组件。我们将客户端脚本组件命名为 Sys.UI._ModalUpdateProgress
,它将是 Sys.UI._UpdateProgress
的子类。
以下是 GetScriptDescriptors()
和 GetScriptReferences():
的详细实现
/// <summary>
/// Gets the script descriptors.
/// </summary>
/// <returns>A list of components, behaviors, and
/// client controls required
/// for the ModalUpdateProgress control's client functionality
/// </returns>
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
if (((this.Page != null) && this.ScriptManager
.SupportsPartialRendering) && this.Visible)
{
ScriptControlDescriptor desc = new ScriptControlDescriptor(
"Sys.UI._ModalUpdateProgress", this.ClientID);
string updatePanelClientID = null;
if (!string.IsNullOrEmpty(this.AssociatedUpdatePanelID))
{
UpdatePanel panel = this.NamingContainer.FindControl(this
.AssociatedUpdatePanelID) as UpdatePanel;
if (panel == null)
{
panel = this.Page.FindControl(this
.AssociatedUpdatePanelID) as UpdatePanel;
}
if (panel == null)
{
throw new InvalidOperationException(string.Format(
CultureInfo.InvariantCulture, "No UpdatePanel
found for AssociatedUpdatePanelID '{0}'.",
new object[] { this.AssociatedUpdatePanelID }));
}
updatePanelClientID = panel.ClientID;
}
string backgroundCssClass = null;
string cancelControlID = null;
if (!string.IsNullOrEmpty(this._backgroundCssClass))
{
backgroundCssClass = this._backgroundCssClass;
}
if (!string.IsNullOrEmpty(this._cancelControlID))
{
cancelControlID = this._cancelControlID;
}
desc.AddProperty("associatedUpdatePanelId", updatePanelClientID);
desc.AddProperty("dynamicLayout", this.DynamicLayout);
desc.AddProperty("displayAfter", this.DisplayAfter);
desc.AddProperty("backgroundCssClass", backgroundCssClass);
desc.AddProperty("cancelControlID", cancelControlID);
yield return desc;
}
}
/// <summary>
/// Gets the script references.
/// </summary>
/// <returns>A list of client script library dependencies for the control.
/// </returns>
protected override IEnumerable<ScriptReference> GetScriptReferences()
{
yield return new ScriptReference("AjaxControls.ModalUpdateProgress.js", "
AjaxControls");
}
这两个方法都返回 IEnumerable
,这些稍后将由 ScriptManager
处理。
为了实现客户端脚本组件 Sys.UI._ModalUpdateProgress
,我们可以从 AJAX Control Toolkit 中提供的 ModalPopup
控件中借用脚本。为了让脚本能够为控件工作,我必须进行一些小的调整,这里就不讨论了。对于那些感兴趣的人,请查看源代码中的 ModalUpdateProgress.js 以了解详细实现。
如何使用
就像 UpdateProgress
控件一样,你可以使用 ProgressTemplate
属性在 ModalUpdateProgress
中自定义你的进度指示器。
ModalUpdateProgress
控件有一个额外的属性 BackgroundCssClass
,用于设置控件显示时背景的 CSS 类。此外,ProgressTemplate 可以包含一个按钮,用户可以单击该按钮以取消正在进行的更新。为了使取消按钮起作用,你应该使用 ProgressTemplate
中的按钮 ID 指定 CancelControlID
属性。
下面显示了将 ModalUpdateProgress
添加到页面的一个示例
<asp:ModalUpdateProgress ID="ModalUpdateProgress1" DisplayAfter="0"
runat="server" BackgroundCssClass="modalBackground">
<ProgressTemplate>
<div class="modalPopup">
Loading <img src="indicator.gif" align="middle" />
</div>
</ProgressTemplate>
</asp:ModalUpdateProgress>
要查看它的工作原理,请查看我包含在下载中的演示网站。ModalUpdateProgress
控件支持 UpdateProgress
的所有功能,包括将 ModalUpdateProgress
与 UpdatePanel
关联。
该控件在 IE6/7 和 Firefox 2.0 下通过了测试。如果你发现任何问题,请在此处留下你的评论。