先说说几个教训:
1,小心命名,别跟系统已经存在的命名起冲突,比如,我一时疏忽将控件的命名空间设成Control,编译通过后,运行总是不通过,查了半天,才发现这个小问题,再比如,NAMEspace别和类名相同,否则,写起来很是不方便
下面是WEBTIMER的全部代码加了注解的
using
System;
using System.Web.UI;
using System.Text;
using System.Web;
using System.Data;
using System.ComponentModel;
namespace MyControl
{
/**//// <summary>
/// WebTimer 的摘要说明。
/// </summary>
///Designer属性指定一个类作为设计时类,该类必须派生于ControlDesigner类,并且实现GetDesignHtml方法
///Designer性性是System.ComponentModel空间的类
///WebTimer继承了IPostBackEventHandler是因为任何要利用POSTBACK机制来进行事件处理的控件都必须
///继承该接口并实现RaisePostbackEvent方法
[Designer(typeof(MyControl.WebTimerDesigner))]
public class WebTimer:System.Web.UI.Control,System.Web.UI.IPostBackEventHandler
{
成员变量定义#region 成员变量定义
private int _interval=5000;//计时器种子数
private bool _enable=true;//是否允许此计时器
private static object TimerKey=new object();//TimerKey是做什么用的呢,它是用来做Events的KEY对象的,而且它是静态的,所以,对于类的所有实例,将只耗费一个变量的代价
#endregion
属性定义#region 属性定义
[Browsable(true),Bindable(true),DefaultValue(5000),Description("计时器使用的种子数")]
public int Interval
{
set{_interval=value;}
get{return(_interval);}
}
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否允许计时器")]
public bool Enable
{
get{return _enable;}
set{_enable=true;}
}
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否输出控件")]
public override bool Visible
{
get
{return base.Visible;}
set
{base.Visible = value;}
}
#endregion
事件定义#region 事件定义
public event EventHandler Timer
{
add {Events.AddHandler(TimerKey,value);}
remove{Events.RemoveHandler(TimerKey,value);}
}
#endregion
方法定义#region 方法定义
/**//// <summary>
/// 这个私有方法是用来在引发POSTBACK事件后,调用事件处理的关键,它再调用相应的事件处理程序
/// </summary>
private void ProcessTimer(string eventArgument)
{
EventHandler TimerHandler=(EventHandler)Events[TimerKey];
if(TimerHandler!=null)
TimerHandler(this,EventArgs.Empty);
}
private string BuildJavascript()
{
StringBuilder JsBuilder=new StringBuilder();
JsBuilder.AppendFormat("<script language='javascript'>setTimeout(\"{0}\",{1});</script>",new object[]{Page.GetPostBackEventReference(this),Interval});
return(JsBuilder.ToString());
}
#endregion
IPostBackEventHandler 成员#region IPostBackEventHandler 成员
/**//// <summary>
/// 每个要使用POSTBACK机制并且想在POSTBACK后进行适当处理的控件
/// 必须实现IPostBackEventHandler的RaisePostBackEvent方法
/// 并在此方法中调用或间接调用事件处理程序
/// </summary>
/// <param name="eventArgument"></param>
public void RaisePostBackEvent(string eventArgument)
{
// TODO: 添加 WebTimer.RaisePostBackEvent 实现
ProcessTimer("");
}
#endregion
OnRender方法用来输出HTML#region OnRender方法用来输出HTML
protected override void Render(HtmlTextWriter writer)
{
if(Page!=null)
Page.VerifyRenderingInServerForm(this);
if(_enable)
writer.Write(BuildJavascript());
}
#endregion
OnPreRender方法用来产生HTML#region OnPreRender方法用来产生HTML
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
Page.GetPostBackEventReference(this,"");
//发现这一句可以不加,如果见了的话呢,DOPOSTBACK将会被绘制在前面,否则,绘制在后面
}
#endregion
}
}
using System.Web.UI;
using System.Text;
using System.Web;
using System.Data;
using System.ComponentModel;
namespace MyControl
{
/**//// <summary>
/// WebTimer 的摘要说明。
/// </summary>
///Designer属性指定一个类作为设计时类,该类必须派生于ControlDesigner类,并且实现GetDesignHtml方法
///Designer性性是System.ComponentModel空间的类
///WebTimer继承了IPostBackEventHandler是因为任何要利用POSTBACK机制来进行事件处理的控件都必须
///继承该接口并实现RaisePostbackEvent方法
[Designer(typeof(MyControl.WebTimerDesigner))]
public class WebTimer:System.Web.UI.Control,System.Web.UI.IPostBackEventHandler
{
成员变量定义#region 成员变量定义
private int _interval=5000;//计时器种子数
private bool _enable=true;//是否允许此计时器
private static object TimerKey=new object();//TimerKey是做什么用的呢,它是用来做Events的KEY对象的,而且它是静态的,所以,对于类的所有实例,将只耗费一个变量的代价
#endregion
属性定义#region 属性定义
[Browsable(true),Bindable(true),DefaultValue(5000),Description("计时器使用的种子数")]
public int Interval
{
set{_interval=value;}
get{return(_interval);}
}
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否允许计时器")]
public bool Enable
{
get{return _enable;}
set{_enable=true;}
}
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否输出控件")]
public override bool Visible
{
get
{return base.Visible;}
set
{base.Visible = value;}
}
#endregion
事件定义#region 事件定义
public event EventHandler Timer
{
add {Events.AddHandler(TimerKey,value);}
remove{Events.RemoveHandler(TimerKey,value);}
}
#endregion
方法定义#region 方法定义
/**//// <summary>
/// 这个私有方法是用来在引发POSTBACK事件后,调用事件处理的关键,它再调用相应的事件处理程序
/// </summary>
private void ProcessTimer(string eventArgument)
{
EventHandler TimerHandler=(EventHandler)Events[TimerKey];
if(TimerHandler!=null)
TimerHandler(this,EventArgs.Empty);
}
private string BuildJavascript()
{
StringBuilder JsBuilder=new StringBuilder();
JsBuilder.AppendFormat("<script language='javascript'>setTimeout(\"{0}\",{1});</script>",new object[]{Page.GetPostBackEventReference(this),Interval});
return(JsBuilder.ToString());
}
#endregion
IPostBackEventHandler 成员#region IPostBackEventHandler 成员
/**//// <summary>
/// 每个要使用POSTBACK机制并且想在POSTBACK后进行适当处理的控件
/// 必须实现IPostBackEventHandler的RaisePostBackEvent方法
/// 并在此方法中调用或间接调用事件处理程序
/// </summary>
/// <param name="eventArgument"></param>
public void RaisePostBackEvent(string eventArgument)
{
// TODO: 添加 WebTimer.RaisePostBackEvent 实现
ProcessTimer("");
}
#endregion
OnRender方法用来输出HTML#region OnRender方法用来输出HTML
protected override void Render(HtmlTextWriter writer)
{
if(Page!=null)
Page.VerifyRenderingInServerForm(this);
if(_enable)
writer.Write(BuildJavascript());
}
#endregion
OnPreRender方法用来产生HTML#region OnPreRender方法用来产生HTML
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
Page.GetPostBackEventReference(this,"");
//发现这一句可以不加,如果见了的话呢,DOPOSTBACK将会被绘制在前面,否则,绘制在后面
}
#endregion
}
}
相应的Designer
using
System;
using System.Web.UI;
using System.Web.UI.Design;
using System.Text;
namespace MyControl
{
/**//// <summary>
/// WebTimerDesigner 的摘要说明。
/// </summary>
public class WebTimerDesigner:System.Web.UI.Design.ControlDesigner
{
public override string GetDesignTimeHtml()
{
StringBuilder HtmlBuilder=new StringBuilder();
Control TimerControl=(Control)this.Component;
if(TimerControl is MyControl.WebTimer)
{
HtmlBuilder.AppendFormat("<span id=\"{0}\" style=\"border:1px solid #666666;font-size:9pt;font-weight:bold\" >{1}</span>",new object[]{TimerControl.ClientID,"WebTimer"});
}
return(HtmlBuilder.ToString());
}
}
}
using System.Web.UI;
using System.Web.UI.Design;
using System.Text;
namespace MyControl
{
/**//// <summary>
/// WebTimerDesigner 的摘要说明。
/// </summary>
public class WebTimerDesigner:System.Web.UI.Design.ControlDesigner
{
public override string GetDesignTimeHtml()
{
StringBuilder HtmlBuilder=new StringBuilder();
Control TimerControl=(Control)this.Component;
if(TimerControl is MyControl.WebTimer)
{
HtmlBuilder.AppendFormat("<span id=\"{0}\" style=\"border:1px solid #666666;font-size:9pt;font-weight:bold\" >{1}</span>",new object[]{TimerControl.ClientID,"WebTimer"});
}
return(HtmlBuilder.ToString());
}
}
}
调用页面的HTML
<%
@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="TimerDemo.WebForm1"
%>
<% @ Register TagPrefix="cc1" Namespace="MyControl" Assembly="MyControl.WebTimer" %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< HTML >
< HEAD >
< title > WebForm1 </ title >
< meta name ="GENERATOR" Content ="Microsoft Visual Studio .NET 7.1" >
< meta name ="CODE_LANGUAGE" Content ="C#" >
< meta name ="vs_defaultClientScript" content ="JavaScript" >
< meta name ="vs_targetSchema" content ="http://schemas.microsoft.com/intellisense/ie5" >
</ HEAD >
< body MS_POSITIONING ="GridLayout" >
< form id ="Form1" method ="post" runat ="server" >
< cc1:WebTimer id ="WebTimer1" runat ="server" ></ cc1:WebTimer >
</ form >
</ body >
</ HTML >
<% @ Register TagPrefix="cc1" Namespace="MyControl" Assembly="MyControl.WebTimer" %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< HTML >
< HEAD >
< title > WebForm1 </ title >
< meta name ="GENERATOR" Content ="Microsoft Visual Studio .NET 7.1" >
< meta name ="CODE_LANGUAGE" Content ="C#" >
< meta name ="vs_defaultClientScript" content ="JavaScript" >
< meta name ="vs_targetSchema" content ="http://schemas.microsoft.com/intellisense/ie5" >
</ HEAD >
< body MS_POSITIONING ="GridLayout" >
< form id ="Form1" method ="post" runat ="server" >
< cc1:WebTimer id ="WebTimer1" runat ="server" ></ cc1:WebTimer >
</ form >
</ body >
</ HTML >
using
System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace TimerDemo
{
/**//// <summary>
/// WebForm1 的摘要说明。
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected MyControl.WebTimer WebTimer1;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.WebTimer1.Timer += new System.EventHandler(this.WebTimer1_Timer);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void WebTimer1_Timer(object sender, System.EventArgs e)
{
Response.Write(DateTime.Now);
}
}
}
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace TimerDemo
{
/**//// <summary>
/// WebForm1 的摘要说明。
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected MyControl.WebTimer WebTimer1;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.WebTimer1.Timer += new System.EventHandler(this.WebTimer1_Timer);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void WebTimer1_Timer(object sender, System.EventArgs e)
{
Response.Write(DateTime.Now);
}
}
}