[转贴]原创控件代码共享--日期选择控件

思路:实现日期年月日的选择
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
{
 /// <summary>
 /// AspNetDate 选择输入日期控件
 /// </summary> 
 [DefaultProperty("Text"),
  ParseChildren(false),
  PersistChildren(false),
  Description("专用于ASP.Net Web应用程序的日期控件"),
  Designer(typeof(DateDesigner)),
  ToolboxData("<{0}:JSYNetDate runat=server></{0}:JSYNetDate>")]
 public class JSYNetDate: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'>

//原创:贾世义 日期:2005-08-16 免费共享 v1.0
//邮箱:jsyhello76@126.com
//请尊重版权,可以随意使用,但请注明出处//

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(" onchange=\"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(" onchange=\"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("&nbsp;");
    }
    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

 }

posted @ 2005-08-18 09:17  PointNet  阅读(850)  评论(1编辑  收藏  举报