由3个dropdownlist组成的选择日期控件
可以设置相应属性
代码如下:
using
System;
using
System.Collections;
using
System.Collections.Specialized;
using
System.ComponentModel;
using
System.IO;
using
System.Text;
using
System.Web.UI;
using
System.Web.UI.Design.WebControls;
using
System.Web.UI.WebControls;

namespace
AppCode

...
{

/**//// <summary>
/// AspNetDate 选择输入日期控件
/// </summary>
[DefaultProperty("Text"),
ParseChildren(false),
PersistChildren(false),
Description("专用于ASP.Net Web应用程序的日期控件"),
Designer(typeof(DateDesigner)),
ToolboxData("<{0}:WSCDate runat=server></{0}:WSCDate>")]
public class WSCDate:Panel,INamingContainer,IPostBackDataHandler

...{

属性#region 属性

/**//// <summary>
/// 获取/设置日期值。
/// </summary>
[Bindable(true),
Browsable(true),
Description("日期值"),
Category("外观"),
DefaultValue("")]
public string Text

...{
get

...{
if (ViewState["Text"] != null)

...{
return ViewState["Text"].ToString();
}
else

...{
if (IsNull)

...{
return "";
}
else

...{
DateTime date=System.DateTime.Today;
string str="";
switch (DateFormat)

...{
case "YMD":
str=date.ToString("yyyy-MM-dd",System.Globalization.DateTimeFormatInfo.InvariantInfo);
break;
case "YM":
str=date.ToString("yyyy-MM",System.Globalization.DateTimeFormatInfo.InvariantInfo);
break;
case "Y":
str=date.Year.ToString();
break;
}
return str;
}
}
}

set

...{
if (value=="")

...{
ViewState["Text"] = "";
}
else if (DateFormat=="YMD")

...{
DateTime date;
try

...{
date=Convert.ToDateTime(value);
}
catch

...{
date=System.DateTime.Today;
}
string str = date.ToString("yyyy-MM-dd",System.Globalization.DateTimeFormatInfo.InvariantInfo);
if (str=="1900-01-01")
str="";
ViewState["Text"] =str;
}
else

...{
ViewState["Text"] = value;
}
}
}

/**//// <summary>
/// 获取/设置日期值是否允许空。
/// </summary>
[Browsable(true),
Description("日期值是否允许空"),
Category("布局"),
DefaultValue(false)]
public bool IsNull

...{
get

...{
return (ViewState["IsNull"]==null)?false:true;
}
set

...{
if (value)
ViewState["IsNull"]=true;
}
}

/**//// <summary>
/// 获取/设置日期值格式(YMD:年-月-日 YM:年-月 Y:年)。
/// </summary>
[Browsable(true),
Description("日期值格式(YMD:年-月-日 YM:年-月 Y:年)"),
Category("布局"),
DefaultValue("YMD")]
public string DateFormat

...{
get

...{
return (ViewState["DateFormat"]==null)?"YMD":(string)ViewState["DateFormat"];
}

set

...{
ViewState["DateFormat"]=value;
}
}

/**//// <summary>
/// 获取/设置日期值能否编辑。
/// </summary>
[Browsable(true),
Description("能否编辑"),
Category("行为"),
DefaultValue(true)]
public override bool Enabled

...{
get

...{
return (ViewState["Enabled"]==null)?true:false;
}

set

...{
if (!value)
ViewState["Enabled"]=false;
}
}

/**//// <summary>
/// 获取/设置日期值中可供选择的年份长度。
/// </summary>
[Browsable(true),
Description("日期值中可供选择的年份长度"),
Category("布局"),
DefaultValue(100)]
public int Length

...{
get

...{
object obj=ViewState["Length"];
return (obj==null)?100:(int)obj;
}

set

...{
ViewState["Length"]=value;
}
}

/**//// <summary>
/// 获取/设置选择年份的结束值。
/// </summary>
[Browsable(true),
Description("日期值中选择结束年份,当小于100时表示距今年数"),
Category("布局"),
DefaultValue(0)]
public int End

...{
get

...{
object obj=ViewState["End"];
int y;
if (obj==null)

...{
y=System.DateTime.Today.Year;
}
else

...{
y=(int)obj;
if (y<100)

...{
y=System.DateTime.Today.Year+y;
}
}
return y;
}

set

...{
ViewState["End"]=value;
}
}

/**//// <summary>
/// 获取选择年份的开始值。
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Start

...{

get...{return End-Length;}
}

#endregion

重写事件#region 重写事件

/**//// <summary>
/// 重写OnLoad 方法。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="EventArgs"/> 对象。</param>
protected override void OnLoad(EventArgs e)

...{
if (Page.IsPostBack)

...{
string y=Page.Request.Form[this.UniqueID+"_year"];
string m=Page.Request.Form[this.UniqueID+"_month"];
string d=Page.Request.Form[this.UniqueID+"_day"];
switch (DateFormat)

...{
case "YMD":
if (y=="" || m=="" || d=="")

...{
Text="";
}
else

...{
Text=y+"-"+m+"-"+d;
}
break;
case "YM":
if (y=="" || m=="")

...{
Text="";
}
else

...{
Text=y+"-"+m;
}
break;
case "Y":
if (y=="")

...{
Text="";
}
else

...{
Text=y;
}
break;
}
}
base.OnLoad(e);
}

/**//// <summary>
/// 重写<see cref="System.Web.UI.WebControls.WebControl.AddAttributesToRender"/> 方法,验证是否有form(runat=server)控件
/// </summary>
/// <param name="writer"></param>
protected override void AddAttributesToRender(HtmlTextWriter writer)

...{
if(this.Page!=null)
this.Page.VerifyRenderingInServerForm(this);
base.AddAttributesToRender(writer);
}

/**//// <summary>
/// 重写<see cref="System.Web.UI.Control.OnPreRender"/>方法。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="EventArgs"/> 对象。</param>
protected override void OnPreRender(EventArgs e)

...{
string strJS=@"<script language='javascript'>

function InitYear(pName,start,length,y)
{
var selYear=eval('document.forms[0].'+pName+'_year');
var n=selYear.length;
selYear.length=n+length+1;
for (i=0;i<=length;i++)
{
selYear.options[n+i].value=(i+start);
selYear.options[n+i].text=(i+start);
}
if (y==0)
{
selYear.selectedIndex =0;
}
else
{
if (y>start)
{
if (y-start<=length)
{
selYear.selectedIndex = n+y-start;
}
else
{
selYear.selectedIndex = length;
}
}
}
}

function InitMonth(pName,m)
{
var selMonth=eval('document.all.'+pName+'_month');
var n=selMonth.length;
selMonth.length=n+12;
for (i=1;i<10;i++)
{
selMonth.options[n+i-1].value='0'+i;
selMonth.options[n+i-1].text=i;
}
for (i=10;i<=12;i++)
{
selMonth.options[n+i-1].value=i;
selMonth.options[n+i-1].text=i;
}
if (m==0)
{
selMonth.selectedIndex=0;
}
else
{
selMonth.selectedIndex = n+m-1;
}
}

function InitDay(pName,d)
{
var selDay=eval('document.all.'+pName+'_day');
var n=selDay.length;
selDay.length=n+31;
for (i=1;i<10;i++)
{
selDay.options[n+i-1].value='0'+i;
selDay.options[n+i-1].text=i;
}
for (i=10;i<=31;i++)
{
selDay.options[n+i-1].value=i;
selDay.options[n+i-1].text=i;
}
if (d==0)
{
selDay.selectedIndex = 0;
}
else
{
selDay.selectedIndex = n+d-1;
}
dateChange(pName);
}

function dateChange(pName)
{
var selYear=eval('document.forms[0].'+pName+'_year');
var year=selYear.options[selYear.selectedIndex].value;
if (year!='')
{
var selMonth=eval('document.all.'+pName+'_month');
var month=selMonth.options[selMonth.selectedIndex].value;
if (month!='')
{
var date=new Date(year,month,0);
var day=date.getDate();
var selDay=eval('document.all.'+pName+'_day');
var tmp=1;
if (selDay.selectedIndex>0)
{
tmp=selDay.options[selDay.selectedIndex].value;
}
selDay.length=day;
for (i=1;i<10;i++)
{
selDay.options[i-1].value='0'+i;
selDay.options[i-1].text=i;
}
for (i=10;i<=day;i++)
{
selDay.options[i-1].value=i;
selDay.options[i-1].text=i;
}
if (tmp>day)
{
selDay.selectedIndex=day-1;
}
else
{
selDay.selectedIndex=tmp-1;
}
}
}
}

</script>";
Page.RegisterClientScriptBlock("EnableDays",strJS);
base.OnPreRender(e);
}

/**//// <summary>
/// 将此控件呈现给指定的输出参数。
/// </summary>
/// <param name="writer"> 要写出到的 HTML 编写器 </param>
protected override void Render(HtmlTextWriter writer)

...{
writer.Write("<table border='0' cellpadding='0' cellspacing='0'><tr><td nowrap align='left'>");
int y=0;
int m=0;
int d=0;
string str=Text;
if (str.Length>=4)

...{
y=Convert.ToInt32(str.Substring(0,4));
if (str.Length>=7)

...{
m=Convert.ToInt32(str.Substring(5,2));
if (str.Length>=10)

...{
d=Convert.ToInt32(str.Substring(8,2));
}
}
}
bool isDate=(DateFormat=="YMD");
if (Enabled)

...{
bool isNull=IsNull;
writer.Write("<select name='"+this.UniqueID+"_year'");
if (isDate)

...{
writer.Write(" οnchange="dateChange('"+this.UniqueID+"')"");
}
writer.Write(">");
if (isNull)

...{
writer.Write("<option value=''></option>");
}
writer.Write("</select>年");
if (DateFormat.Length>1)

...{
writer.Write("<select name='"+this.UniqueID+"_month'");
if (isDate)

...{
writer.Write(" οnchange="dateChange('"+this.UniqueID+"')"");
}
writer.Write(">");
if (isNull)

...{
writer.Write("<option value=''></option>");
}
writer.Write("</select>月");
writer.Write(@"
<script language='javascript'>
InitYear('"+this.UniqueID+"',"+Start.ToString()+","+Length.ToString()+","+y.ToString()+@");
InitMonth('"+this.UniqueID+"',"+m.ToString()+@");
</script>");
if (isDate)

...{
writer.Write("<select name='"+this.UniqueID+"_day'>");
if (isNull)

...{
writer.Write("<option value=''></option>");
}
writer.Write("</select>日");
writer.Write(@"
<script language='javascript'>
InitDay('"+this.UniqueID+"',"+d.ToString()+@");
</script>");
}
}
}
else

...{
if (y==0 || m==0)

...{
writer.Write(" ");
}
else

...{
writer.Write(y.ToString()+"年"+m.ToString()+"月");
if (d!=0)

...{
writer.Write(d.ToString()+"日");
}
}
}
writer.Write("</td></tr></table>");
}

public event EventHandler TextChanged;


/**//// <summary>
/// 当由类实现时,为 ASP.NET 服务器控件处理回发数据。
/// </summary>
/// <param name="postDataKey">控件的主要标识符</param>
/// <param name="postCollection">所有传入名称值的集合</param>
/// <returns>如果服务器控件的状态在回发发生后更改,则为 true;否则为 false。</returns>
public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)

...{
String presentValue = Text;
String postedValue = postCollection[postDataKey];

if (presentValue == null || !presentValue.Equals(postedValue))

...{
Text = postedValue;
return true;
}

return false;
}


/**//// <summary>
/// 当由类实现时,用信号要求服务器控件对象通知 ASP.NET 应用程序该控件的状态已更改。
/// </summary>
public virtual void RaisePostDataChangedEvent()

...{
OnTextChanged(EventArgs.Empty);
}

protected virtual void OnTextChanged(EventArgs e)

...{
if (TextChanged != null)
TextChanged(this,e);
}
#endregion

}



控件设计器#region 控件设计器

/**//// <summary>
/// 服务器控件设计器。
/// </summary>
public class DateDesigner:System.Web.UI.Design.WebControls.PanelDesigner

...{

/**//// <summary>
/// 初始化 PagerDesigner 的新实例。
/// </summary>
public DateDesigner()

...{
this.ReadOnly=true;
}
private WSCDate wb;


/**//// <summary>
/// 获取用于在设计时表示关联控件的 HTML。
/// </summary>
/// <returns>用于在设计时表示控件的 HTML。</returns>
public override string GetDesignTimeHtml()

...{

wb=(WSCDate)Component;
wb.Text="";
StringWriter sw=new StringWriter();
HtmlTextWriter writer=new HtmlTextWriter(sw);
wb.RenderControl(writer);
return sw.ToString();
}


/**//// <summary>
/// 获取在呈现控件时遇到错误后在设计时为指定的异常显示的 HTML。
/// </summary>
/// <param name="e">要为其显示错误信息的异常。</param>
/// <returns>设计时为指定的异常显示的 HTML。</returns>
protected override string GetErrorDesignTimeHtml(Exception e)

...{
string errorstr="创建控件时出错:"+e.Message;
return CreatePlaceHolderDesignTimeHtml(errorstr);
}
}
#endregion
}
使用方法:在asp.net 页中加入
<%@ Register TagPrefix="cc1" Namespace="AppCode" Assembly="AppCode" %>
<cc1:wscdate id="WSCDate1" runat="server" IsNull="False" Length="46" End="2050" Wrap="False"></cc1:wscdate>