锁定 ASP.NET 页面并在等待长 POST 回显时显示动画图像
锁定页面,防止回发
引言
问题
Web 中最普遍的问题之一是提交后需要很长时间才能处理的页面。假设您有一个 ASP.NET 表单,处理时间长达 30 秒,用户会不断地按提交按钮两到三次,希望能更快地获得信息(这可能会导致数据问题)。解决此问题的一种方法是在提交按钮被按下后禁用它。但如果您的表单中有多个按钮怎么办?
解决方案
在本文中,我将向您展示如何在 POST 回显期间禁用所有 ASP.NET 表单的控件,并在页面 POST 回显时向用户显示一个友好的动画 GIF。事实上,如果您对漫长的等待感到厌烦,甚至可以移动这个小框。

Yahoo to Yahoo
Yahoo 为我们提供了一个完整的、可供下载并在我们的 Web 应用程序中免费使用的 JavaScript 框架!那么为什么不利用它呢?您可以在此处找到有关它的更多信息。
在本文中,我将仅使用 Yahoo YUI 的Panel
对象。以下是入门的几个简单步骤:
从此处下载框架脚本到您的项目(v. 2.7)。
框架应该在一个名为YUI的目录中(我下载了 2.7.0 版本)。将此目录复制到您的 Web 项目中,您的 Web 项目应如下所示:

Show Me the Money Jerry!
现在我们已经在项目中设置了 Yahoo Framework,我们可以开始工作了!以下是设置您的 ASP.NET 页面以充分利用Panel
对象的几个简单步骤(此处)。
在 HTML 的<head>
标签下,包含这些 JavaScript 文件:
<!-- YUI CSS -->
<link rel="stylesheet" type="text/css" href="yui/build/container/assets/container.css"/>
<link rel="stylesheet" type="text/css" href="yui/build/menu/assets/skins/sam/menu.css"/>
<!-- YUI Dependencies -->
<script type="text/javascript" src="yui/build/utilities/utilities.js" ></script>
<script type="text/javascript" src="yui/build/container/container-min.js"></script>
<script type="text/javascript">
让我们创建几个简单的 JavaScript 函数:让我们开始初始化Panel
,标题为“正在加载,请稍候…”并使用一个名为Wait.gif的动画 GIF(您可以为该对象添加更多属性,请阅读 Yahoo 文档)。
// sets up all of the YUI dialog boxes
function InitDialogs() {
DialogBox_Loading = new YAHOO.widget.Panel("waitBox",
{ fixedcenter: true, modal: true, visible: true,
width: "230px", close: false, draggable: true });
DialogBox_Loading.setHeader("Loading, please wait...");
DialogBox_Loading.setBody('<div style="text-align:center;">
<img src="images/Wait.gif" id="Image1" /></div>');
DialogBox_Loading.render(document.body);
}
让我们创建一个 JavaScript 函数,该函数负责根据布尔值显示或隐藏“等待框”。我们还想确保 ASP.NET 页面是有效的(所有 ASP.NET 验证控件都已成功)之后,我们才显示Panel
对象。我们可以使用客户端的Page_IsValid
标志来检查这一点。为了获取此标志,我们被迫在按下按钮时调用 .NET 生成的 JavaScript 方法Page_ClientValidate();
。我将在文章稍后展示这一点。
function Loading(b) {
if (b == true && Page_IsValid == true) {
DialogBox_Loading.show();
}
else {
DialogBox_Loading.hide();
}
}
对于此示例,我添加了 AJAX 脚本管理器,以便可以在客户端使用pageLoaded()
事件。要了解更多信息,请在此处访问。如果您不想使用 Ajax Framework,那么我们需要自己连接 JavaScript 中的页面加载事件。这是一个如何做的示例:让我们添加一个帮助 JavaScript 函数,它将为页面加载事件调用我们想要的任何函数。我已经将该示例包含在我的下载示例项目中的YahooWaitLoadOnButtonServerNoAjax.aspx下。这是一个使用 JavaScript 实现此功能的有效示例:
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
// wire up the PageLoad function with our helper function addLoadEvent
addLoadEvent(function() {
pageLoad();
})
在 Page Load 事件中,我将初始化 Dialog 框而不显示它。
function pageLoad() {
InitDialogs();
Loading(false);
}
现在我们准备创建一些 ASP.NET 控件,让我们创建一个文本框、一个 Required Field Validator 和一个需要 30 多秒才能处理的 ASP.NET 按钮。我们将把几个 JavaScript 调用链接到我们的按钮。
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="false" />
<div>
<asp:TextBox ID="txtFirstName" runat ="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="VtxtFirstName" ControlToValidate="txtFirstName"
ErrorMessage="error" runat="server"></asp:RequiredFieldValidator>
<asp:Button ID="btnPushLongJob" Text ="Start Long Job" runat="server"
OnClientClick="Page_ClientValidate();Loading(true);" OnClick="btnPushLongJob_Click"/>
</div>
</form>
</body>
我正在调用Page_ClientValidate()
,这是一个由我的 ASP.NET Validator 控件生成的 JavaScript 函数。我被迫调用它,以便它可以设置客户端的Page_isValid
标志,该标志在Loading
JavaScript 函数中使用。并且我调用Loading(true)
来显示 Dialog 框。
现在,让我们在代码隐藏中为按钮的Onclick
事件添加一个长时间处理的任务(记住添加System.Threading
命名空间以使用Thread
类)。
protected void btnPushLongJob_Click(object sender, EventArgs e)
{
Thread.Sleep(30000);
}
问题:GIF 动画在 POST 回显期间停止
嗯,生活有时很艰难,并非一切都如预期般工作。由于某些原因,Internet Explorer 决定让我们的生活更艰难,并在 POST 回显期间停止所有 GIF 动画,但有一个解决方法,我现在就免费向您展示(我很善良,对吧?)。在 JavaScript 中重置图像源似乎可以解决此问题。
我添加了以下 JavaScript 代码:
function UpdateImg(ctrl, imgsrc) {
var img = document.getElementById(ctrl);
img.src = imgsrc;
}
并且我在 Page Load 事件中从代码隐藏将其链接到我的 ASP.NET 按钮。
protected void Page_Load(object sender, EventArgs e)
{
btnPushLongJob.Attributes.Add("onclick",
"setTimeout(\"UpdateImg('Image1','images/Wait.gif');\",50);");
}
这样我们就完成了!
这是一个完整的页面代码:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="YahooWaitLoadOnButtonServerSide.aspx.cs"
Inherits="YahooWaitLoadOnButtonServerSide" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<!-- YUI CSS -->
<link rel="stylesheet" type="text/css" href="yui/build/container/assets/container.css"/>
<link rel="stylesheet" type="text/css" href="yui/build/menu/assets/skins/sam/menu.css"/>
<!-- YUI Dependencies -->
<script type="text/javascript" src="yui/build/utilities/utilities.js" ></script>
<script type="text/javascript" src="yui/build/container/container-min.js"></script>
<script type="text/javascript">
function pageLoad() {
InitDialogs();
Loading(false);
}
function UpdateImg(ctrl, imgsrc) {
var img = document.getElementById(ctrl);
img.src = imgsrc;
}
// sets up all of the YUI dialog boxes
function InitDialogs() {
DialogBox_Loading = new YAHOO.widget.Panel("waitBox",
{ fixedcenter: true, modal: true, visible: true,
width: "230px", close: false, draggable: true });
DialogBox_Loading.setHeader("Loading, please wait...");
DialogBox_Loading.setBody('<div style="text-align:center;">
<img src="images/Wait.gif" id="Image1" /></div>');
DialogBox_Loading.render(document.body);
}
function Loading(b) {
if (b == true && Page_IsValid == true) {
DialogBox_Loading.show();
}
else {
DialogBox_Loading.hide();
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="false" />
<div>
<asp:TextBox ID="txtFirstName" runat ="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="VtxtFirstName"
ControlToValidate="txtFirstName" ErrorMessage="error"
runat="server"></asp:RequiredFieldValidator>
<asp:Button ID="btnPushLongJob" Text ="Start Long Job" runat="server"
OnClientClick="Page_ClientValidate();Loading(true);" OnClick="btnPushLongJob_Click"/>
</div>
</form>
</body>
</html>
这是代码隐藏文件的完整代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
public partial class YahooWaitLoadOnButtonServerSide : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
btnPushLongJob.Attributes.Add("onclick",
"setTimeout(\"UpdateImg('Image1','images/Wait.gif');\",50);");
}
protected void btnPushLongJob_Click(object sender, EventArgs e)
{
Thread.Sleep(3000);
}
}
代码
我创建了一个包含 Yahoo YUI 2.7 Framework 的示例项目。您可能想尝试YahooWaitLoadOnButtonServerSide.aspx页面作为此示例(对于没有 Ajax 支持的情况,请查看YahooWaitLoadOnButtonServerNoAjax.aspx页面)。我还包含了一些其他示例,例如工具提示和使用 Page Methods 的 Dialog 框。
您可以通过本文顶部的链接下载代码。
希望您喜欢这篇文章,并且它让您的生活变得更轻松。