原创控件代码共享--日期选择控件

思路:实现日期年月日的选择
1、可以设定年的起止年份
2、排除不正确日期选择的可能
3、使用javascript实现控制
4、使用Text属性方便获取设置日期值

代码如下:
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 JSY
{
///

1<summary>   
2/// AspNetDate 选择输入日期控件   
3/// </summary>

[DefaultProperty("Text"),
ParseChildren(false),
PersistChildren(false),
Description("专用于ASP.Net Web应用程序的日期控件"),
Designer(typeof(DateDesigner)),
ToolboxData("<{0}:JSYNetDate runat=server>

")]
public class JSYNetDate:Panel,INamingContainer,IPostBackDataHandler
{
#region 属性
///

1<summary>   
2/// 获取/设置日期值。   
3/// </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;
}
}
}
///

1<summary>   
2/// 获取/设置日期值是否允许空。   
3/// </summary>

[Browsable(true),
Description("日期值是否允许空"),
Category("布局"),
DefaultValue(false)]
public bool IsNull
{
get
{
return (ViewState["IsNull"]==null)?false:true;
}
set
{
if (value)
ViewState["IsNull"]=true;
}
}
///

1<summary>   
2/// 获取/设置日期值格式(YMD:年-月-日 YM:年-月 Y:年)。   
3/// </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;
}
}
///

1<summary>   
2/// 获取/设置日期值能否编辑。   
3/// </summary>

[Browsable(true),
Description("能否编辑"),
Category("行为"),
DefaultValue(true)]
public override bool Enabled
{
get
{
return (ViewState["Enabled"]==null)?true:false;
}

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

1<summary>   
2/// 获取/设置日期值中可供选择的年份长度。   
3/// </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;
}
}
///

1<summary>   
2/// 获取/设置选择年份的结束值。   
3/// </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;
}
}
///

1<summary>   
2/// 获取选择年份的开始值。   
3/// </summary>

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int Start
{
get{return End-Length;}
}

#endregion
#region 重写事件
///

1<summary>   
2/// 重写OnLoad 方法。   
3/// </summary>

///

1<param name="e"/>

包含事件数据的

1<see cref="EventArgs"></see>

对象。
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);
}
///

1<summary>   
2/// 重写<see cref="System.Web.UI.WebControls.WebControl.AddAttributesToRender"></see> 方法,验证是否有form(runat=server)控件   
3/// </summary>

///

1<param name="writer"/>

protected override void AddAttributesToRender(HtmlTextWriter writer)
{
if(this.Page!=null)
this.Page.VerifyRenderingInServerForm(this);
base.AddAttributesToRender(writer);
}
///

1<summary>   
2/// 重写<see cref="System.Web.UI.Control.OnPreRender"></see>方法。   
3/// </summary>

///

1<param name="e"/>

包含事件数据的

1<see cref="EventArgs"></see>

对象。
protected override void OnPreRender(EventArgs e)
{
string strJS=@"

  1<script language="javascript">
  2
  3//原创:贾世义 日期:2005-08-16 免费共享 v1.0   
  4//邮箱: [email protected]   
  5//请尊重版权,可以随意使用,但请注明出处// 
  6
  7function InitYear(pName,start,length,y)   
  8{   
  9var selYear=eval('document.forms[0].'+pName+'_year');   
 10var n=selYear.length;   
 11selYear.length=n+length+1;   
 12for (i=0;i<=length;i++)   
 13{   
 14selYear.options[n+i].value=(i+start);   
 15selYear.options[n+i].text=(i+start);   
 16}   
 17if (y==0)   
 18{   
 19selYear.selectedIndex =0;   
 20}   
 21else   
 22{   
 23if (y>start)   
 24{   
 25if (y-start<=length)   
 26{   
 27selYear.selectedIndex = n+y-start;   
 28}   
 29else   
 30{   
 31selYear.selectedIndex = length;   
 32}   
 33}   
 34}   
 35} 
 36
 37function InitMonth(pName,m)   
 38{   
 39var selMonth=eval('document.all.'+pName+'_month');   
 40var n=selMonth.length;   
 41selMonth.length=n+12;   
 42for (i=1;i<10;i++)   
 43{   
 44selMonth.options[n+i-1].value='0'+i;   
 45selMonth.options[n+i-1].text=i;   
 46}   
 47for (i=10;i<=12;i++)   
 48{   
 49selMonth.options[n+i-1].value=i;   
 50selMonth.options[n+i-1].text=i;   
 51}   
 52if (m==0)   
 53{   
 54selMonth.selectedIndex=0;   
 55}   
 56else   
 57{   
 58selMonth.selectedIndex = n+m-1;   
 59}   
 60} 
 61
 62function InitDay(pName,d)   
 63{   
 64var selDay=eval('document.all.'+pName+'_day');   
 65var n=selDay.length;   
 66selDay.length=n+31;   
 67for (i=1;i<10;i++)   
 68{   
 69selDay.options[n+i-1].value='0'+i;   
 70selDay.options[n+i-1].text=i;   
 71}   
 72for (i=10;i<=31;i++)   
 73{   
 74selDay.options[n+i-1].value=i;   
 75selDay.options[n+i-1].text=i;   
 76}   
 77if (d==0)   
 78{   
 79selDay.selectedIndex = 0;   
 80}   
 81else   
 82{   
 83selDay.selectedIndex = n+d-1;   
 84}   
 85dateChange(pName);   
 86} 
 87
 88function dateChange(pName)   
 89{   
 90var selYear=eval('document.forms[0].'+pName+'_year');   
 91var year=selYear.options[selYear.selectedIndex].value;   
 92if (year!='')   
 93{   
 94var selMonth=eval('document.all.'+pName+'_month');   
 95var month=selMonth.options[selMonth.selectedIndex].value;   
 96if (month!='')   
 97{   
 98var date=new Date(year,month,0);   
 99var day=date.getDate();   
100var selDay=eval('document.all.'+pName+'_day');   
101var tmp=1;   
102if (selDay.selectedIndex>0)   
103{   
104tmp=selDay.options[selDay.selectedIndex].value;   
105}   
106selDay.length=day;   
107for (i=1;i<10;i++)   
108{   
109selDay.options[i-1].value='0'+i;   
110selDay.options[i-1].text=i;   
111}   
112for (i=10;i<=day;i++)   
113{   
114selDay.options[i-1].value=i;   
115selDay.options[i-1].text=i;   
116}   
117if (tmp>day)   
118{   
119selDay.selectedIndex=day-1;   
120}   
121else   
122{   
123selDay.selectedIndex=tmp-1;   
124}   
125}   
126}   
127} 
128
129</script>

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

1<summary>   
2/// 将此控件呈现给指定的输出参数。   
3/// </summary>

///

1<param name="writer"/>

要写出到的 HTML 编写器
protected override void Render(HtmlTextWriter writer)
{
writer.Write("

 1<table border="0" cellpadding="0" cellspacing="0"><tr><td align="left" nowrap="">");   
 2int y=0;   
 3int m=0;   
 4int d=0;   
 5string str=Text;   
 6if (str.Length&gt;=4)   
 7{   
 8y=Convert.ToInt32(str.Substring(0,4));   
 9if (str.Length&gt;=7)   
10{   
11m=Convert.ToInt32(str.Substring(5,2));   
12if (str.Length&gt;=10)   
13{   
14d=Convert.ToInt32(str.Substring(8,2));   
15}   
16}   
17}   
18bool isDate=(DateFormat=="YMD");   
19if (Enabled)   
20{   
21bool isNull=IsNull;   
22writer.Write("<select ");="" (isdate)="" if="" name='"+this.UniqueID+"_year' onchange="\&quot;dateChange('&quot;+this.UniqueID+&quot;')\&quot;&quot;);" writer.write("="" {="" }="">");   
23if (isNull)   
24{   
25writer.Write("<option value=""></option>");   
26}   
27writer.Write("</select>年");   
28if (DateFormat.Length&gt;1)   
29{   
30writer.Write("<select ");="" (isdate)="" if="" name='"+this.UniqueID+"_month' onchange="\&quot;dateChange('&quot;+this.UniqueID+&quot;')\&quot;&quot;);" writer.write("="" {="" }="">");   
31if (isNull)   
32{   
33writer.Write("<option value=""></option>");   
34}   
35writer.Write("</select>月");   
36writer.Write(@"   
37<script language="javascript">   
38InitYear('"+this.UniqueID+"',"+Start.ToString()+","+Length.ToString()+","+y.ToString()+@");   
39InitMonth('"+this.UniqueID+"',"+m.ToString()+@");   
40</script>");   
41if (isDate)   
42{   
43writer.Write("<select name='"+this.UniqueID+"_day'>");   
44if (isNull)   
45{   
46writer.Write("<option value=""></option>");   
47}   
48writer.Write("</select>日");   
49writer.Write(@"   
50<script language="javascript">   
51InitDay('"+this.UniqueID+"',"+d.ToString()+@");   
52</script>");   
53}   
54}   
55}   
56else   
57{   
58if (y==0 || m==0)   
59{   
60writer.Write(" ");   
61}   
62else   
63{   
64writer.Write(y.ToString()+"年"+m.ToString()+"月");   
65if (d!=0)   
66{   
67writer.Write(d.ToString()+"日");   
68}   
69}   
70}   
71writer.Write("</td></tr></table>

");
}

public event EventHandler TextChanged;

///

1<summary>   
2/// 当由类实现时,为 ASP.NET 服务器控件处理回发数据。   
3/// </summary>

///

1<param name="postDataKey"/>

控件的主要标识符
///

1<param name="postCollection"/>

所有传入名称值的集合
///

1<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;
}

///

1<summary>   
2/// 当由类实现时,用信号要求服务器控件对象通知 ASP.NET 应用程序该控件的状态已更改。   
3/// </summary>

public virtual void RaisePostDataChangedEvent()
{
OnTextChanged(EventArgs.Empty);
}

protected virtual void OnTextChanged(EventArgs e)
{
if (TextChanged != null)
TextChanged(this,e);
}
#endregion

}

#region 控件设计器
///

1<summary>   
2/// 服务器控件设计器。   
3/// </summary>

public class DateDesigner:System.Web.UI.Design.WebControls.PanelDesigner
{
///

1<summary>   
2/// 初始化 PagerDesigner 的新实例。   
3/// </summary>

public DateDesigner()
{
this.ReadOnly=true;
}
private JSYNetDate wb;

///

1<summary>   
2/// 获取用于在设计时表示关联控件的 HTML。   
3/// </summary>

///

1<returns>用于在设计时表示控件的 HTML。</returns>

public override string GetDesignTimeHtml()
{

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

///

1<summary>   
2/// 获取在呈现控件时遇到错误后在设计时为指定的异常显示的 HTML。   
3/// </summary>

///

1<param name="e"/>

要为其显示错误信息的异常。
///

1<returns>设计时为指定的异常显示的 HTML。</returns>

protected override string GetErrorDesignTimeHtml(Exception e)
{
string errorstr="创建控件时出错:"+e.Message;
return CreatePlaceHolderDesignTimeHtml(errorstr);
}
}
#endregion
}

把以上代码保存为一个文件,如:JSYNetDate.cs
使用csc /t:library /out:..\bin\JSY.dll /r:System.Web.dll /r:System.dll JSYNetDate.cs编译即可

请多留宝贵意见,我会继续努力
使用举例

1@ Register TagPrefix="cc1" Namespace="JSY" Assembly="JSY" 
1@ Page language="c#"
 1<html>
 2<head>
 3<title>WebForm1</title>
 4<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR"/>
 5<meta content="C#" name="CODE_LANGUAGE"/>
 6<meta content="JavaScript" name="vs_defaultClientScript"/>
 7<meta content=" http://schemas.microsoft.com/intellisense/ie5 " name="vs_targetSchema"/>
 8</head>
 9<body>
10<form id="Form1" method="post" runat="server">
11<div align="center">
12<cc1:jsynetdate id="JSYNetDate1" isnull="true" length="50" runat="server"></cc1:jsynetdate>
13<asp:button id="Button1" runat="server" text="Button"></asp:button>
14</div>
15</form>
16</body>
17</html>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus