Web系统中经常会遇到这样的情况:页面提交很慢,用户耐心受到挑战就开始摧残页面上的按钮,反复点击反而搞得更慢。前两天就遇到这样一个问题,用户要进行大数据量的导出操作,这个服务器端需要比较长的时间处理,于是很容易出现用户等得不耐烦就反复点击导出按钮的情况。
下面是页面代码的一个示例:
<a></a>
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3 <%@ Register Assembly="KingWebControlToolkit" Namespace="KingWebControlToolkit" TagPrefix="King" %>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <html xmlns="http://www.w3.org/1999/xhtml">
6 <head runat="server">
7 <title>Untitled Page</title>
8 </head>
9 <body>
10 <form id="form1" runat="server">
11 <div>
12 <King:LoadingControl runat="server">
13 <ContentTemplate>
14 <asp:Button ID="Button1" runat="server" Text="Button" />
15 </ContentTemplate>
16 <ProgressTemplate>
17 <img src="loader.gif" />Loading
18 </ProgressTemplate>
19 </King:LoadingControl>
20 </div>
21 </form>
22 </body>
23 </html>
24
为了能看到Loading的效果我们在Page_Load中使用System.Threading.Thread.Sleep(3000);做延迟。
页面render出来的代码如下:
<!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><title>
Untitled Page
</title></head>
<body>
<form name="form1" method="post" action="default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEzMTA5NTM4NzBkZLrTZqXsuouOmVoeCXorqE2igxmz" />
</div>
<div>
<span><span onclick="javascript:this.style.display='none';document.getElementById('progress').style.display='';" id="content">
<input type="submit" name="ctl02$Button1" value="Button" id="ctl02_Button1" />
</span><span id="progress" style="display:none">
<img src="loader.gif" />Loading
</span></span>
</div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLd8PGLAgLbhbjtDTVN73GhBUNr1cM8hkjWUdhLBytV" />
</div></form>
</body>
</html>
控件实现
其实就两个要点:
控件要支持两个模板一个是ContentTemplate这个是要隐藏部分的模板,一个是Progress模板用来放Loading的提示信息
添加javascript脚本来实现隐藏,这个利用事件传递的原理可以方便的实现
这个控件超简单直接贴代码了,控件源代码如下:
1
using System;
2
using System.ComponentModel;
3
using System.Drawing;
4
using System.Security.Permissions;
5
using System.Web;
6
using System.Web.UI;
7
using System.Web.UI.WebControls;
8
9
namespace KingWebControlToolkit
10
{
11
[
12
AspNetHostingPermission(SecurityAction.InheritanceDemand,
13
Level = AspNetHostingPermissionLevel.Minimal),
14
AspNetHostingPermission(SecurityAction.Demand,
15
16
ToolboxData(
17
"<{0}:LoadingControl runat=\"server\"> </{0}:LoadingControl>"),
18
]
19
public class LoadingControl : CompositeControl
20
{
21
private ITemplate contentTempalte;
22
private ITemplate progressTemplate;
23
24
private TemplateContainer contentContainer;
25
private TemplateContainer progressContainer;
26
[
27
Browsable(false),
28
DesignerSerializationVisibility(
29
DesignerSerializationVisibility.Hidden)
30
]
31
public TemplateContainer Owner
32
{
33
get
34
{
35
return contentContainer;
36
}
37
}
38
39
40
41
PersistenceMode(PersistenceMode.InnerProperty),
42
DefaultValue(typeof(ITemplate), ""),
43
Description("Control template"),
44
TemplateContainer(typeof(LoadingControl ))
45
46
public virtual ITemplate ContentTemplate
47
48
49
50
return contentTempalte;
51
52
set
53
54
contentTempalte = value;
55
56
57
58
59
60
61
62
63
TemplateContainer(typeof(LoadingControl))
64
65
public virtual ITemplate ProgressTemplate
66
67
68
69
return progressTemplate;
70
71
72
73
progressTemplate = value;
74
75
76
77
protected override void CreateChildControls()
78
79
Controls.Clear();
80
contentContainer = new TemplateContainer();
81
progressContainer = new TemplateContainer();
82
contentContainer.Attributes["onclick"] = "javascript:this.style.display='none';document.getElementById('progress').style.display='';";
83
contentContainer.Attributes["id"] = "content";
84
progressContainer.Attributes["id"] = "progress";
85
progressContainer.Attributes["style"] = "display:none";
86
ITemplate temp = contentTempalte;
87
if (temp == null)
88
89
temp = new DefaultTemplate();
90
91
temp.InstantiateIn(contentContainer);
92
93
temp = progressTemplate;
94
temp.InstantiateIn(progressContainer);
95
this.Controls.Add(contentContainer);
96
this.Controls.Add(progressContainer);
97
98
}
99
100
101
ToolboxItem(false)
102
103
public class TemplateContainer : WebControl
104
105
106
107
DefaultTemplate
117
}
118