动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > ASP.NET技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ ASP.NET技巧 ]的信息



本月文章推荐
.当DataSet中包含主/子表时,Updat.
.用完HttpWebResponse时别忘了调用.
.asp.net如何连接sql server2000数.
.动态修改.Net StreamReader Enco.
.下载文件关闭窗体之解决方法.
.ASP.NET 2.0高级数据处理之处理N.
.怎样从ASP.NET 2.0中读取连接字符.
.在ASP.NET中跨页面实现多选.
.使用ASPX输出XML应注意的问题.
.asp.net(vb.net)连接sql server .
.一个读取扩展名为xml的资源文件的.
.使用ASP.NET2.0的ReportViewer查.
.正则表达式中的组集合的使用.
.利用ASP.NET技术动态生成HTML页面.
.使用HttpWebRequest向网站模拟上.
.得到随机字符串算法.
.ASP.NET底层架构探索之进入.NET运.
.一个在移动设备中获取路径的方法.
.ASP.NET中使用IFRAME建立类Modal.
.ASP.NET Atlas对JavaScript的扩展.

ASP.NET服务器控件PleaseWaitButton[翻译]

发表日期:2006-8-21 |


Introduction

  在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("\"", "&quot;");

    return sCode;
}
  如果指定了一个PleaseWaitImage,就必须包含额外的一段Javascript代码来通知客户端预载该图像。这段脚本的注册应该出现在重写的OnPreRender方法中。注册的键是图像的名称;如果多个按钮都使用同一图像,预载脚本只需要实施一次。这里使用了一个正则表达式来创建Javascript图像变量,以保证特殊字字符(比如文件路径中的斜线)转化成下划线。

 

protected override void OnPreRender(EventArgs e)
{
    base.OnPreRender (e);

    // If we're using an image, register some javascript
    // for client-side image preloading
    if (_pleaseWaitImage != String.Empty
        && _pleaseWaitType != PleaseWaitTypeEnum.TextOnly)
        RegisterJavascriptPreloadImage(_pleaseWaitImage);
}

private void RegisterJavascriptPreloadImage(string sImage)
{
    Regex rex = new Regex("[^a-zA-Z0-9]");
    string sImgName = "img_" + rex.Replace(sImage, "_");

    StringBuilder sb = new StringBuilder();
    sb.Append("<script language='JavaScript'>");
    sb.Append("if (document.images) { ");
    sb.AppendFormat("{0} = new Image();", sImgName);
    sb.AppendFormat("{0}.src = \"{1}\";", sImgName, sImage);
    sb.Append(" } ");
    sb.Append("</script>");

    this.Page.RegisterClientScriptBlock(sImgName + "_PreloadScript",
                                        sb.ToString());
}

Client-side functions

  嵌入的文本文件javascript.txt包含了隐藏按钮的<div>和显示"please wait"信息或图像的客户端代码。这些代码在重写的OnInit()方法中调用的私有方法RegisterJavascriptFromResource()加载。这个方法调用泛型方法GetEmbeddedTextFile() ,在这个泛型方法中把文件做为源加载而把内容返回成字符串。


protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
   
    // the client-side javascript code is kept
    // in an embedded resource; load the script
    // and register it with the page.
    RegisterJavascriptFromResource();
}


private void RegisterJavascriptFromResource()
{  
    // load the embedded text file "javascript.txt"
    // and register its contents as client-side script
    string sScript = GetEmbeddedTextFile("javascript.txt");
    this.Page.RegisterClientScriptBlock("PleaseWaitButtonScript", sScript);
}


private string GetEmbeddedTextFile(string sTextFile)
{
    // generic function for retrieving the contents
    // of an embedded text file resource as a string

    // we'll get the executing assembly, and derive
    // the namespace using the first type in the assembly
    Assembly a = Assembly.GetExecutingAssembly();
    String sNamespace = a.GetTypes()[0].Namespace;

    // with the assembly and namespace, we'll get the
    // embedded resource as a stream
    Stream s = a.GetManifestResourceStream(
                string.Format("{0}.{1}", sNamespace, sTextFile)
            );
   
    // read the contents of the stream into a string
    StreamReader sr = new StreamReader(s);
    String sContents = sr.ReadToEnd();

    sr.Close();
    s.Close();

    return sContents;
}
  javascript.txt嵌入资源包含了按钮在Javascript的onclick句柄中执行的客户端方法PleaseWait()。这段代码也调用了一个客户端方法HideDiv()以隐藏按钮的容器<div>,然后通过设置innerHTML属性把信息或图像组装进之前空的<div>标记中。辅助函数GetDiv()则是通过检查document.getElementById, document.all, 和 document.layers用id返回一个<div>对象,保证了不同浏览器的兼容性。下面是javascript.txt的全部代码:
<script language="JavaScript">
function GetDiv(sDiv)
{
    var div;
    if (document.getElementById)
        div = document.getElementById(sDiv);
    else if (document.all)
        div = eval("window." + sDiv);
    else if (document.layers)
        div = document.layers[sDiv];
    else
        div = null;

    return div;
}

function HideDiv(sDiv)
{
    d = GetDiv(sDiv);
    if (d)
    {
        if (document.layers) d.visibility = "hide";
        else d.style.visibility = "hidden";
    }
}

function PleaseWait(sDivButton, sDivMessage, sInnerHtml)
{
    HideDiv(sDivButton);
    var d = GetDiv(sDivMessage);
    if (d) d.innerHTML = sInnerHtml;
}
</script>

原文链接:http://www.codeproject.com/aspnet/PleaseWaitButton.asp
Download Source Project - 7 Kb
Download Demo Project - 30 Kb

http://www.cnblogs.com/jeffamy/archive/2006/08/20/481952.html

上一篇:ASP.NET 2.0 WebService中传递DataTable参考 人气:5143
下一篇:用gridview显示来自excel表格里的数据 人气:5419
浏览全部ASP.NET的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-23 Menalto Gallery v2.3 Rc1 多国语
2008-7-23 深度学习网址导航系统 v2.6.1
2008-7-23 因特达crm2008客户关系管理系统
2008-7-23 60度 CMS v1.0 Build 080723
2008-7-23 幻影动漫网视频系统(Ppdong) v1.
2008-7-23 好易祝福墙 2008
2008-7-23 APJE私服发布系统 v2.0 PHP版
2008-7-23 毕业论文在线指导系统源码
2008-7-23 Jacky法律在线网站源码
2008-7-19 UltraEdit 简体中文增强版 14.10
2008-7-19 CentOS 5.2 i386 LiveCD
2008-7-19 Snapture多功能相机 v1.4
2008-7-19 iAcces中文输入法 v1.0Build016
2008-7-19 Cookbook烹饪秘籍 v2.5
2008-7-19 苹果专用DVD转换工具 v1.1.59汉化
2008-7-19 Modem修复软件ZiPhone修改版04.0
2008-7-19 AgileMessenger即时通讯工具美化
2008-7-19 Sketches画图软件 v0.7b6破解版


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵