Loading控件--防止用户反复提交 |
| 7/25/2008 3:24:31 PM |
Web系统中经常会遇到这样的情况:页面提交很慢,用户耐心受到挑战就开始摧残页面上的按钮,反复点击反而搞得更慢。前两天就遇到这样一个问题,用户要进行大数据量的导出操作,这个服务器端需要比较长的时间处理,于是很容易出现用户等得不耐烦就反复点击导出按钮的情况。
下面是页面代码的一个示例:
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>
<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 Level = AspNetHostingPermissionLevel.Minimal),
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 Browsable(false),
41 PersistenceMode(PersistenceMode.InnerProperty),
42 DefaultValue(typeof(ITemplate), ""),
43 Description("Control template"),
44 TemplateContainer(typeof(LoadingControl ))
45 ]
46 public virtual ITemplate ContentTemplate
47 {
48 get
49 {
50 return contentTempalte;
51 }
52 set
53 {
54 contentTempalte = value;
55 }
56 }
57
58 [
59 Browsable(false),
60 PersistenceMode(PersistenceMode.InnerProperty),
61 DefaultValue(typeof(ITemplate), ""),
62 Description("Control template"),
63 TemplateContainer(typeof(LoadingControl))
64 ]
65 public virtual ITemplate ProgressTemplate
66 {
67 get
68 {
69 return progressTemplate;
70 }
71 set
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 DefaultTemplate
108 sealed class DefaultTemplate : ITemplate
109 {
110 void ITemplate.InstantiateIn(Control owner)
111 {
112 LiteralControl linebreak = new LiteralControl("<br/><font size='2' color='blue' >没有制定模板内容,显示默认模板<br/>Tip:Tempalte id not defined,using default Tempalte.</font>");
113 owner.Controls.Add(linebreak);
114 }
115 }
116 #endregion
117 }
118
Demo下载:loadingdemo.rar
|
本文附件: loadingdemo.rar
|
| 作者:坚强2002
来源:博客园 |