Asp.Net 基于客户端回调的进度条控件
这是本人第一篇博客,首先相各位博友问个好。博客注册了有好长一段时间, 一直没有时间写点什么东西。最近项目终于不像以前忙了, 想起来写点什么。
前段时间在项目遇到一个长任务显示进度条的问题。 在网上找了好久都没有找到好的控件。要么下下来bug 一堆, 要么就是用起来极端不方便。于是琢磨着自己写一个。站在各位前辈的肩上,花了2 天的时间终于让我弄出来了。
前段时间在项目遇到一个长任务显示进度条的问题。 在网上找了好久都没有找到好的控件。要么下下来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(this, null, "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);
}
}
{
ClientScriptManager csm = this.Page.ClientScript;
string startReference = this.Page.ClientScript.GetCallbackEventReference(this, "0", "UpdateState", null);
string reference = this.Page.ClientScript.GetCallbackEventReference(this, null, "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;
}
}
{
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>
<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() + "个任务");
}
}
{
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() + "个任务");
}
}
调用页面服务器端代码。
至此, 大部分的代码都已经在这儿了。
下载控件