引子
在刚刚发布的
ExtAspNet v2.1.1版本中,应网友
要求添加了ext:Timer控件,实现的效果就是定时回发(AJAX)到服务器执行一段C#代码。
因为这个控件非常简单,没有页面可视元素,所以我就单独拿出来讲解一下,或许对大家阅读ExtAspNet源代码有一定的帮助。
使用Timer控件
先来看下使用Timer的例子(
在线版本):
ASPX标签声明:
<ext:PageManager ID="PageManager1" runat="server" />
<ext:Timer ID="Timer1" Interval="3" Enabled="false" OnTick="Timer1_Tick" runat="server">
</ext:Timer>
<ext:Button ID="btnStartTimer" runat="server" Text="Start Timer" OnClick="btnStartTimer_Click">
</ext:Button>
<ext:Button ID="btnStopTimer" runat="server" Text="Stop Timer" OnClick="btnStopTimer_Click">
</ext:Button>
<br />
<ext:Label ID="labServerTime" runat="server" Text="This is current datetime.">
</ext:Label>
这里定义Timer1每隔3秒回发服务器一次(Interval="3"),默认不启用(Enabled="false"),同时定义后台事件处理函数(OnTick="Timer1_Tick")。
C#代码:
protected void Timer1_Tick(object sender, EventArgs e)
{
labServerTime.Text = DateTime.Now.ToString();
}
protected void btnStartTimer_Click(object sender, EventArgs e)
{
Timer1.Enabled = true;
}
protected void btnStopTimer_Click(object sender, EventArgs e)
{
Timer1.Enabled = false;
}
在每隔3秒的事件处理函数Timer1_Tick中,只是简单的将页面中Label控件的文本改变为当前服务器时间。
ExtAspNet中Timer的实现
[ToolboxData("<{0}:Timer Interval=\"30\" runat=\"server\"></{0}:Timer>")]
[ToolboxBitmap(typeof(Timer), "res.toolbox_icons.Timer.bmp")]
[Description("定时器")]
[DefaultEvent("Tick")]
public class Timer : ControlBase, IPostBackEventHandler
{
#region properties
/// <summary>
/// 是否可用
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(true)]
[Description("是否可用")]
public virtual bool Enabled
{
get
{
object obj = ViewState["Enabled"];
return obj == null ? true : (bool)obj;
}
set
{
ViewState["Enabled"] = value;
}
}
/// <summary>
/// 定时间隔(单位:秒)
/// </summary>
[Category(CategoryName.OPTIONS)]
[DefaultValue(30)]
[Description("定时间隔(单位:秒)")]
public int Interval
{
get
{
object obj = ViewState["Interval"];
return obj == null ? 30 : (int)obj;
}
set
{
ViewState["Interval"] = value;
}
}
#endregion
#region OnPreLoad
protected override void OnPreLoad(object sender, EventArgs e)
{
base.OnPreLoad(sender, e);
SaveAjaxProperty("Enabled", Enabled);
}
#endregion
#region OnPreRender
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// 不渲染
RenderWrapperDiv = false;
string setupScript = String.Format("box.{0}=window.setInterval(function(){{{1}}}, {2});", ClientJavascriptID, GetPostBackEventReference(), Interval * 1000);
if (Enabled)
{
AddPageFirstLoadAbsoluteScript(setupScript);
}
if (AjaxPropertyChanged("Enabled", Enabled))
{
string ajaxScript = String.Format("window.clearInterval(box.{0});", ClientJavascriptID);
if (Enabled)
{
ajaxScript += setupScript;
}
AddAjaxPropertyChangedScript(ajaxScript);
}
}
#endregion
#region IPostBackEventHandler
public void RaisePostBackEvent(string eventArgument)
{
OnTick(EventArgs.Empty);
}
#endregion
#region OnTick
private static readonly object _handlerKey = new object();
/// <summary>
/// 定时事件
/// </summary>
[Category(CategoryName.ACTION)]
[Description("定时事件")]
public event EventHandler Tick
{
add
{
Events.AddHandler(_handlerKey, value);
}
remove
{
Events.RemoveHandler(_handlerKey, value);
}
}
protected virtual void OnTick(EventArgs e)
{
EventHandler handler = Events[_handlerKey] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
#endregion
}
从上往下看,首先是声明两个属性Enabled和Interval,中间OnPreRender是用来向页面中输出JavaScript代码,后面是OnTick事件的定义。
下面主要讲解OnPreRender中的代码:
1. 不考虑AJAX的支持的支持
如果不考虑ExtAspNet中所谓的原声的AJAX支持,我们可以简单的把OnPreRender重写为:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// 不渲染
RenderWrapperDiv = false;
string setupScript = String.Format("box.{0}=window.setInterval(function(){{{1}}}, {2});", ClientJavascriptID, GetPostBackEventReference(), Interval * 1000);
if (Enabled)
{
AddPageFirstLoadAbsoluteScript(setupScript);
}
}
其中RenderWrapperDiv = false,用来说明此控件不需要向页面中输出任何HTML代码。
如果将上例中Enabled属性改为true,则会在页面中生成如下代码:
box.__0=window.setInterval(function(){__doPostBack('Timer1','');}, 3000);
如图:
2. 添加AJAX的支持
如果需要AJAX支持,那么我就需知道在此次的PostBack中,控件的那些属性发生了变化,ExtAspNet提供一套机制来完成这一任务,那就是你所看到的SaveAjaxProperty和AjaxPropertyChanged,我们有
一篇文章专门说明这一问题。
我们来看下在上例中,点击“Start Timer”和“Stop Timer”分别发生了什么:
Start Timer:
Stop Timer:
对比Timer的源代码,是不是很清晰,其实ExtAspNet的控件编写并不是很复杂,如果你有好的想法不妨自己先尝试一下。
下载全部源代码