屯昌旅游网

Asp.Net 基于客户端回调的进度条控件

这是本人第一篇博客,首先相各位博友问个好。博客注册了有好长一段时间, 一直没有时间写点什么东西。最近项目终于不像以前忙了, 想起来写点什么。
      前段时间在项目遇到一个长任务显示进度条的问题。 在网上找了好久都没有找到好的控件。要么下下来bug 一堆, 要么就是用起来极端不方便。于是琢磨着自己写一个。站在各位前辈的肩上,花了2 天的时间终于让我弄出来了。

总的思路就是: 客户端使用Javascript 周期调用回调函数, 从而达到不刷新效果。



废话少说, 来看代码:

protected override void OnPreRender(EventArgs e)
        
{
            ClientScriptManager csm 
= this.Page.ClientScript;
            
string startReference = this.Page.ClientScript.GetCallbackEventReference(this"0""UpdateState"null);
            
string reference = this.Page.ClientScript.GetCallbackEventReference(thisnull"UpdateState"null);
            System.Text.StringBuilder scriptBuilder 
= new StringBuilder();
            scriptBuilder.AppendLine(
"var timerId;");
            scriptBuilder.AppendLine(
"  function start()");

            scriptBuilder.AppendLine(
"{");
            scriptBuilder.AppendLine(startReference 
+ ";");
            scriptBuilder.AppendLine(
" timerId = setInterval( function (){" + reference + "; }," + RefleshTimeSpan + " );");
            scriptBuilder.AppendLine(
"}");
            scriptBuilder.AppendLine(
"function UpdateState(arg, context)");
            scriptBuilder.AppendLine(
"{");
            scriptBuilder.AppendLine(
"if(arg != \"\")");
            scriptBuilder.AppendLine(
" {");
            scriptBuilder.AppendLine(
"var contents = arg.split(\"],[\");");
            scriptBuilder.AppendLine(
"var currentProgress = contents[0].substring(1);");
            scriptBuilder.AppendLine(
"var infoText = contents[1].substring(0, contents[1].length - 1);");

            scriptBuilder.AppendLine(
"document.getElementById(\"innerDiv\").style.width = currentProgress ;");
            
if (!string.IsNullOrEmpty(this.InfoProviderID))
            
{
                scriptBuilder.AppendLine(
"document.getElementById('" + this.InfoProviderID + "').innerText = infoText;");
            }

            scriptBuilder.AppendLine(
"if(currentProgress >= " + this.InnerWidth + ")");
            scriptBuilder.AppendLine(
"{");
            
if (!string.IsNullOrEmpty(this.InfoProviderID))
            
{
                scriptBuilder.AppendLine(
"document.getElementById('" + this.InfoProviderID + "').innerText = infoText;");
            }

            scriptBuilder.AppendLine(
"document.getElementById(\"innerDiv\").style.width = " + this.InnerWidth + ";");
            scriptBuilder.AppendLine(
"window.clearInterval(timerId);");
            scriptBuilder.AppendLine(
"}");
            scriptBuilder.AppendLine(
"}");
            scriptBuilder.AppendLine(
"}");
            
if (!csm.IsStartupScriptRegistered("callback"))
            
{
                csm.RegisterClientScriptBlock(
this.GetType(), "callback", scriptBuilder.ToString(), true);
            }

        }
 

                                                       向客户端注册Javascript

   protected override void RenderContents(HtmlTextWriter output)
        
{
            output.AddAttribute(HtmlTextWriterAttribute.Id, 
"innerDiv");
            
if (this.ProgressBackColor != Color.Empty)
            
{
                output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(ProgressBackColor));
            }

            
if (!ControlStyle.IsEmpty)
            

                
if (!ControlStyle.Height.IsEmpty)
                
{
                    output.AddStyleAttribute(HtmlTextWriterStyle.Height, 
this.Height.Value.ToString());
                }

            }

            
if (!string.IsNullOrEmpty(this.ProgressBackImage))
            
{
                output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, 
string.Format("url({0})"this.ProgressBackImage));
            }

            output.RenderBeginTag(HtmlTextWriterTag.Div);
            output.RenderEndTag();
        }
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

                                                    Render 控件

      ICallbackEventHandler Members

                                            ICallBackEventHandler 接口实现

<body>
    
<form id="form1" runat="server" >
        
<cc1:ProgressControl ID="ProgressControl1" runat="server" Height="35px" Width="535px"  ProgressBackColor="White" BackColor="#FF8080" BorderColor="#C0C0FF" BorderStyle="Solid" BorderWidth="20px" />
    
</form>
   
<span id="span1" runat="server" enableviewstate="false">
    
       
<script language="javascript" type="text/javascript"> start(); </script> </span>
</body>

     使用Javascript 函数start() 进行调用。 本来想把调用封装成一个服务器端方法, 但是由于asp.net无法控制javascript 的注册顺序。只好通过客户端来调用。 各位如果有什么好的注意,不凡告诉我一声。

    protected void Page_Load(object sender, EventArgs e)
    
{
        
this.ProgressControl1.MaxProgress = 100;
        
this.ProgressControl1.TaskStartDelegate = new System.Threading.ThreadStart(ProcessMethod);
        
this.ProgressControl1.InfoProviderID = this.span1.ID;
    }


    
public void ProcessMethod()
    
{
        
for (int i = 0; i < 101; i++)
        
{
            Thread.Sleep(
100);
            
this.ProgressControl1.Progress = i;
            
this.ProgressControl1.SetInfoText("已经进行到第" + i.ToString() + "个任务");
        }

    }

                                         调用页面服务器端代码。

至此, 大部分的代码都已经在这儿了。
下载控件

posted on 2008-05-30 09:50  welkin  阅读(1044)  评论(4编辑  收藏  举报

导航

屯昌旅游网