先说说几个教训:
1,小心命名,别跟系统已经存在的命名起冲突,比如,我一时疏忽将控件的命名空间设成Control,编译通过后,运行总是不通过,查了半天,才发现这个小问题,再比如,NAMEspace别和类名相同,否则,写起来很是不方便
下面是WEBTIMER的全部代码加了注解的
using System;
using System.Web.UI;
using System.Text;
using System.Web;
using System.Data;
using System.ComponentModel;
![](/Images/OutliningIndicators/None.gif)
namespace MyControl
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <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
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
成员变量定义#region 成员变量定义
private int _interval=5000;//计时器种子数
private bool _enable=true;//是否允许此计时器
private static object TimerKey=new object();//TimerKey是做什么用的呢,它是用来做Events的KEY对象的,而且它是静态的,所以,对于类的所有实例,将只耗费一个变量的代价
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
属性定义#region 属性定义
[Browsable(true),Bindable(true),DefaultValue(5000),Description("计时器使用的种子数")]
public int Interval
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{_interval=value;}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{return(_interval);}
}
![](/Images/OutliningIndicators/InBlock.gif)
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否允许计时器")]
public bool Enable
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{return _enable;}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{_enable=true;}
}
![](/Images/OutliningIndicators/InBlock.gif)
[Browsable(true),Bindable(true),DefaultValue(true),Description("是否输出控件")]
public override bool Visible
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{return base.Visible;}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{base.Visible = value;}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
事件定义#region 事件定义
public event EventHandler Timer
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
add
{Events.AddHandler(TimerKey,value);}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
remove
{Events.RemoveHandler(TimerKey,value);}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
方法定义#region 方法定义
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 这个私有方法是用来在引发POSTBACK事件后,调用事件处理的关键,它再调用相应的事件处理程序
/// </summary>
private void ProcessTimer(string eventArgument)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
EventHandler TimerHandler=(EventHandler)Events[TimerKey];
if(TimerHandler!=null)
TimerHandler(this,EventArgs.Empty);
}
![](/Images/OutliningIndicators/InBlock.gif)
private string BuildJavascript()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
StringBuilder JsBuilder=new StringBuilder();
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
JsBuilder.AppendFormat("<script language='javascript'>setTimeout(\"
{0}\",{1});</script>",new object[]
{Page.GetPostBackEventReference(this),Interval});
return(JsBuilder.ToString());
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IPostBackEventHandler 成员#region IPostBackEventHandler 成员
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 每个要使用POSTBACK机制并且想在POSTBACK后进行适当处理的控件
/// 必须实现IPostBackEventHandler的RaisePostBackEvent方法
/// 并在此方法中调用或间接调用事件处理程序
/// </summary>
/// <param name="eventArgument"></param>
public void RaisePostBackEvent(string eventArgument)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// TODO: 添加 WebTimer.RaisePostBackEvent 实现
ProcessTimer("");
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
OnRender方法用来输出HTML#region OnRender方法用来输出HTML
protected override void Render(HtmlTextWriter writer)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(Page!=null)
Page.VerifyRenderingInServerForm(this);
if(_enable)
writer.Write(BuildJavascript());
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
OnPreRender方法用来产生HTML#region OnPreRender方法用来产生HTML
protected override void OnPreRender(EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// WebTimerDesigner 的摘要说明。
/// </summary>
public class WebTimerDesigner:System.Web.UI.Design.ControlDesigner
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public override string GetDesignTimeHtml()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
StringBuilder HtmlBuilder=new StringBuilder();
Control TimerControl=(Control)this.Component;
if(TimerControl is MyControl.WebTimer)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
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
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%
@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="TimerDemo.WebForm1" %>
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%
@ 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;
![](/Images/OutliningIndicators/None.gif)
namespace TimerDemo
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// WebForm1 的摘要说明。
/// </summary>
public class WebForm1 : System.Web.UI.Page
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
protected MyControl.WebTimer WebTimer1;
private void Page_Load(object sender, System.EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 在此处放置用户代码以初始化页面
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.WebTimer1.Timer += new System.EventHandler(this.WebTimer1_Timer);
this.Load += new System.EventHandler(this.Page_Load);
![](/Images/OutliningIndicators/InBlock.gif)
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
private void WebTimer1_Timer(object sender, System.EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Response.Write(DateTime.Now);
}
}
}