ASP.NET服务器控件PleaseWaitButton[翻译] (1)
点击次数:16 次 发布日期:2008-11-26 12:25:08 作者:源代码网
|
源代码网推荐 源代码网推荐 在web application的表单提交过程中显示“please wait”信息或者是gif动画图片通常是很有用的,特别是提交过程比较久的情况。我最近开发了一个调查提交程序,在程序里内部用户通过一个网页上传excel电子表格。程序将上传的电子表格数据插入到数据库中。这个过程只需要几秒钟,但即便是几秒钟,在网页是看来却是非常明显的等待过程。在程序测试的时候,一些用户重复地点击上传按钮。因此,提供一个视觉的信息来告诉人们上传正在进行中是很有用的。并同时把上传按钮一起隐藏掉,以防止多次点击。这里介绍的控件是Button控件的子类,它演示了如何把客户端javascript代码封装在asp.net服务器控件中来提供便利的功能。 源代码网推荐 源代码网推荐 虽然外面已经有很多javascript的例子来完成这件事情,但当我试图把这些功能封装到asp.net控件中时我发现了一些问题。我最开始尝试通过javascript的onclick句柄来使button无效,并用另外的文本取代。但我发现很棘手,这样会妨碍到asp.net服务器端的click事件的功能。而最终行得通的,并且对不同浏览器也有很好支持的方法是,让button在div标记中呈现。div可以隐藏并且不妨碍asp.net的click事件。 源代码网推荐 源代码网推荐 Using the control 源代码网推荐 源代码网推荐 作为正常的button控件的派生,PleaseWaitButton的功能与它基本一样。它通过三个附加的属性来管理当按钮被点击后"please Wait"信息或图片的显示。 源代码网推荐 源代码网推荐 PleaseWaitText 源代码网推荐 这是显示的客户端文本信息,如果存在,当按钮被点击它将取代按钮。 源代码网推荐 PleaseWaitImage 源代码网推荐 这是显示的图像文件(比如gif动画图像),如果存在,当按钮被点击它将取代按钮。这个属性将变成<img>标记中的src属性。 源代码网推荐 PleaseWaitType 源代码网推荐 PleaseWaitTypeEnum枚举值之一:TextOnly,ImageOnly,TextThenImage,或者ImageThenText。它控制消息和图片的布局。 源代码网推荐 源代码网推荐 下面是一个.aspx文件示例,它演示了一个设置了PleaseWaitText和PleaseWaitImage的PleastWaitButton。 源代码网推荐 源代码网推荐 源代码网推荐 源代码网推荐 <%@ Page language="C#" %> 源代码网推荐 <%@ Register TagPrefix="cc1" Namespace="JavaScriptControls" 源代码网推荐 Assembly="PleaseWaitButton" %> 源代码网推荐 源代码网推荐 <script runat="server"> 源代码网推荐 private void PleaseWaitButton1_Click(object sender, System.EventArgs e) 源代码网推荐 { 源代码网推荐 // Server-side Click event handler; 源代码网推荐 源代码网推荐 // simulate something that could take a long time, 源代码网推荐 // like a file upload or time-consuming server processing 源代码网推荐 源代码网推荐 DateTime dt = DateTime.Now.AddSeconds(5); 源代码网推荐 while (DateTime.Now < dt) 源代码网推荐 { 源代码网推荐 // do nothing; simulate a 5-second pause 源代码网推荐 } 源代码网推荐 源代码网推荐 // at the end of the loop display a success message 源代码网推荐 // and hide the submit form 源代码网推荐 panelSuccess.Visible = true; 源代码网推荐 PleaseWaitButton1.Visible = false; 源代码网推荐 } 源代码网推荐 </script> 源代码网推荐 源代码网推荐 <html> 源代码网推荐 <head> 源代码网推荐 <title>Testing PleaseWaitButton</title> 源代码网推荐 </head> 源代码网推荐 <body> 源代码网推荐 <form id="Form1" method="post" runat="server"> 源代码网推荐 源代码网推荐 <P>Testing the PleaseWaitButton control.</p> 源代码网推荐 源代码网推荐 <cc1:PleaseWaitButton id="PleaseWaitButton1" runat="server" 源代码网推荐 Text="Click me to start a time-consuming process" 源代码网推荐 PleaseWaitText="Please Wait " 源代码网推荐 PleaseWaitImage="pleaseWait.gif" 源代码网推荐 OnClick="PleaseWaitButton1_Click" /> 源代码网推荐 源代码网推荐 <asp:Panel id="panelSuccess" runat="server" 源代码网推荐 visible="false"> 源代码网推荐 Thank you for submitting this form. You are truly 源代码网推荐 the coolest user I"ve ever had the pleasure of serving. 源代码网推荐 No, really, I mean it. There have been others, sure, 源代码网推荐 but you are really in a class by yourself. 源代码网推荐 </asp:Panel> 源代码网推荐 源代码网推荐 </form> 源代码网推荐 </body> 源代码网推荐 </html> 源代码网推荐 源代码网推荐 源代码网推荐 How It Works 源代码网推荐 源代码网推荐 PleaseWaitButton控件在<div>标记中呈现了一个标准的asp.net Button。它也呈现了一个空的<div>标记给 源代码网推荐 信息/图像。在点击按钮时,由Javascript函数(见下面的客户端函数)控制按钮的隐藏和信息的显示。为了方便起见,由PleaseWaitButton服务器控件处理所有必需的javascript客户端代码的实施。 源代码网推荐 由于PleaseWaitButton实施它自己的javascript onclick句柄,所以我们必须采取一些额外的措施来保持原有的onclick句柄,并且允许控件清晰地运行一些客户端验证代码。为了达到此目的,我们首先把Button基类还原为一个字符串缓冲,然后巧妙地处理它,把我们定义的onclick代码包含进去。 源代码网推荐 源代码网推荐 源代码网推荐 protected override void Render(HtmlTextWriter output) 源代码网推荐 { 源代码网推荐 // Output the button"s html (with attributes) 源代码网推荐 // to a dummy HtmlTextWriter 源代码网推荐 StringWriter sw = new StringWriter(); 源代码网推荐 HtmlTextWriter wr = new HtmlTextWriter(sw); 源代码网推荐 base.Render(wr); 源代码网推荐 string sButtonHtml = sw.ToString(); 源代码网推荐 wr.Close(); 源代码网推荐 sw.Close(); 源代码网推荐 // now modify the code to include an "onclick" handler 源代码网推荐 // with our PleaseWait() function called appropriately 源代码网推荐 // after any client-side validation. 源代码网推荐 sButtonHtml = ModifyJavaScriptOnClick(sButtonHtml); 源代码网推荐 源代码网推荐 // before rendering the button, output an empty <div> 源代码网推荐 // that will be populated client-side via javascript 源代码网推荐 // with a "please wait" message" 源代码网推荐 output.Write(string.Format("<div id="pleaseWaitButtonDiv2_{0}">", 源代码网推荐 this.ClientID)); 源代码网推荐 output.Write("</div>"); 源代码网推荐 源代码网推荐 // render the button in an encapsulating <div> tag of its own 源代码网推荐 output.Write(string.Format("<div id="pleaseWaitButtonDiv_{0}">", 源代码网推荐 this.ClientID)); 源代码网推荐 output.Write(sButtonHtml); 源代码网推荐 output.Write("</div>"); 源代码网推荐 } 源代码网推荐 这种把button还原成一个字符串缓冲然后处理它的onclick内容的技术是一件很危险的事情(is certainly a hack). 但它可以让我们在父button类中实施标准的验证代码,然后再实现我们的PleaseWait() Javascript函数调用。如果不这样做,我们只能在验证代码之前就在onclick属性中实施我们的PleaseWait()函数调用,除非我们愿意完全重写父Button类的属性的呈现。这样就算页面上有输入错误也会产生我们并不希望的按钮隐藏和显示"please wait"信息的效果。因此,我们必须在onclick句柄中强行令我们的客户端PleaseWait()函数出现在客户端页面验证之后。 源代码网推荐 onclick属性的修改发生在ModifyJavaScriptOnClick()函数中。这个函数获取按钮呈现的HTML字符串,并检查看是否存在onclick属性。如果是,这个函数会检查是否有使用客户端验证代码。如果是这种情况的话,我们定义的PleaseWait()函数会加在已经存在的onclick代码的最后面,紧跟在客户端检查的boolin变量Page_IsValid后面。这个变量代表是否使用了验证控件。如果Page_IsValid的值是false,"Please wait"信息将不显示。如果为True则显示。 源代码网推荐 private string ModifyJavaScriptOnClick(string sHtml) 源代码网推荐 { 源代码网推荐 // Thanks to CodeProject member KJELLSJ (Kjell-Sverre Jerijaervi) 源代码网推荐 // for code ideas to allow the button to work with client-side validation 源代码网推荐 源代码网推荐 string sReturn = ""; 源代码网推荐 string sPleaseWaitCode = GeneratePleaseWaitJavascript(); 源代码网推荐 源代码网推荐 // is there an existing onclick attribute? 源代码网推荐 Regex rOnclick = new Regex("onclick="(?<onclick>[^"]*)"); 源代码网推荐 Match mOnclick = rOnclick.Match(sHtml); 源代码网推荐 if (mOnclick.Success) 源代码网推荐 { 源代码网推荐 // there is an existing onclick attribute; 源代码网推荐 // add our code to the end of it; if client-side 源代码网推荐 // validation has been rendered, make sure 源代码网推荐 // we check to see if the page is valid; 源代码网推荐 string sExisting = mOnclick.Groups["onclick"].Value; 源代码网推荐 string sReplace = sExisting 源代码网推荐 + (sExisting.Trim().EndsWith(";") ? "" : "; "); 源代码网推荐 源代码网推荐 if (IsValidatorIncludeScript() && this.CausesValidation) 源代码网推荐 { 源代码网推荐 // include code to check if the page is valid 源代码网推荐 string sCode = "if (Page_IsValid) " + sPleaseWaitCode 源代码网推荐 + " return Page_IsValid;"; 源代码网推荐 // add our code to the end of the existing onclick code; 源代码网推荐 sReplace = sReplace + sCode; 源代码网推荐 } 源代码网推荐 else 源代码网推荐 { 源代码网推荐 // don"t worry about the page being valid; 源代码网推荐 sReplace = sReplace + sPleaseWaitCode; 源代码网推荐 } 源代码网推荐 源代码网推荐 // now substitute our onclick code 源代码网推荐 sReplace = "onclick="" + sReplace; 源代码网推荐 sReturn = rOnclick.Replace(sHtml, sReplace); 源代码网推荐 } 源代码网推荐 else 源代码网推荐 { 源代码网推荐 // there isn"t an existing onclick attribute; 源代码网推荐 // add ours 源代码网推荐 int i = sHtml.Trim().Length - 2; 源代码网推荐 string sInsert = " onclick="" + sPleaseWaitCode + "" "; 源代码网推荐 sReturn = sHtml.Insert(i, sInsert); 源代码网推荐 } 源代码网推荐 源代码网推荐 return sReturn; 源代码网推荐 源代码网推荐 } 源代码网推荐 源代码网推荐 这个IsValidatorIncludeScript() 利用上面的检查来查看是否有使用页面注册的asp.net验证控件的标准Javascript代码块。下面则用一个简单的方法测试了是否有验证代码和像Page_IsValid的变量存在。 源代码网推荐 private bool IsValidatorIncludeScript() 源代码网推荐 { 源代码网推荐 // return TRUE if this page has registered javascript 源代码网推荐 // for client-side validation; this code may not be registered 源代码网推荐 // if ASP.NET detects what it thinks (correctly or incorrectly) 源代码网推荐 // is a down-level browser. 源代码网推荐 源代码网推荐 return this.Page.IsStartupScriptRegistered("ValidatorIncludeScript"); 源代码网推荐 } 下面这个GeneratePleaseWaitJavascript()构建了包含在onclick属性中的PleaseWait() Javascript函数。我们可以通过检查控件的属性来决定想要的布局。 源代码网推荐 private string GeneratePleaseWaitJavascript() 源代码网推荐 { 源代码网推荐 // create a JavaScript "PleaseWait()" function call 源代码网推荐 // suitable for use in an onclick event handler 源代码网推荐 源代码网推荐 string sMessage = ""; 源代码网推荐 string sText = _pleaseWaitText; 源代码网推荐 string sImage = (_pleaseWaitImage != String.Empty 源代码网推荐 ? string.Format( 源代码网推荐 "<img src="{0}" align="absmiddle" alt="{1}"/>" 源代码网推荐 , _pleaseWaitImage, _pleaseWaitText ) 源代码网推荐 : String.Empty); 源代码网推荐 源代码网推荐 // establish the layout based on PleaseWaitType 源代码网推荐 switch (_pleaseWaitType) 源代码网推荐 { 源代码网推荐 case PleaseWaitTypeEnum.TextThenImage: 源代码网推荐 sMessage = sText + sImage; 源代码网推荐 break; 源代码网推荐 case PleaseWaitTypeEnum.ImageThenText: 源代码网推荐 sMessage = sImage + sText; 源代码网推荐 break; 源代码网推荐 case PleaseWaitTypeEnum.TextOnly: 源代码网推荐 sMessage = sText; 源代码网推荐 break; 源代码网推荐 case PleaseWaitTypeEnum.ImageOnly: 源代码网推荐 sMessage = sImage; 源代码网推荐 break; 源代码网推荐 } 源代码网推荐 源代码网推荐 // return the final code chunk 源代码网推荐 string sCode = string.Format( 源代码网推荐 "PleaseWait("pleaseWaitButtonDiv_{0}", 源代码网推荐 "pleaseWaitButtonDiv2_{1}", "{2}");" 源代码网推荐 , this.ClientID, this.ClientID, sMessage); 源代码网推荐 sCode = sCode.Replace(""", """); 源代码网推荐 源代码网推荐 return sCode; 源代码网推荐 } 源代码网推荐 源代码网推荐 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
