Asp.net 自定义控件之Calendar Picker/Date Picker

日期选择控件 是开发项目很常用的控件 拥有一个功能强大的date picker控件 可以工作的得心应手.
这个日期选择控件具有一下特性:
服务器端控件 , 可以方便的拖放.
js日历使用的是http://www.dynarch.com/projects/calendar/ 支持多国语言 支持多种风格 支持多种浏览器 等等
设置选取日期或时间日期
设置是否能手动修改日期
设置默认显示的日期
提供DateChanged事件,方便编程.
效果如图:



现在直接给出代码   来自Cuyahoga这个项目 做了一点点修改
aspx
<cc1:CalendarPicker ID="CalendarPicker1" Theme="win2k_cold_2" runat="server"/>
CalendarPicker.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Collections.Specialized;

namespace Jec.CustomControls
{
    
/// <summary>
    
/// 使用的js日历
    
/// (http://www.dynarch.com/projects/calendar/). 
    
/// </summary>
    [DefaultProperty("Text"), ToolboxData("<{0}:CalendarPicker runat=server></{0}:CalendarPicker>")]
    [ValidationProperty(
"Text")]
    
public class CalendarPicker : WebControl, INamingContainer
    {
        
private TextBox _dateTextBox;
        
private Image _calendarImage;

        
#region properties
        [Bindable(
true), Category("Appearance"), DefaultValue("")]
        
public string Text
        {
            
get
            {
                EnsureChildControls();
                
return this._dateTextBox.Text;
            }
            
set
            {
                EnsureChildControls();
                
this._dateTextBox.Text = value;
            }
        }
        
//calendar样式
        [Bindable(true), Category("Appearance"), DefaultValue(CalendarTheme.system)]
        
public CalendarTheme Theme
        {
            
get { return (ViewState["Theme"!= null ? (CalendarTheme)ViewState["Theme"] : CalendarTheme.system); }
            
set { ViewState["Theme"= value; }
        }
        
//calendar语言
        [Bindable(true), Category("Behavior"), DefaultValue(CalendarLanguage.en)]
        
public CalendarLanguage Language
        {
            
get { return (ViewState["Language"!= null ? (CalendarLanguage)ViewState["Language"] : CalendarLanguage.en); }
            
set { ViewState["Language"= value; }
        }
        
//输入框是否允许手工输入
        [Bindable(true), Category("Behavior"), DefaultValue(false)]
        
public bool IsReadOnly
        {
            
get { return (ViewState["IsReadOnly"!= null ? (bool)ViewState["IsReadOnly"] : false); }
            
set { ViewState["IsReadOnly"= value; }
        }
        
//calendar js文件所在的文件夹
        [Bindable(true), Category("Behavior"), DefaultValue("~/Support/JsCalendar")]
        
public string SupportDir
        {
            
get { return (ViewState["SupportDir"!= null ? (string)ViewState["SupportDir"] : ""); }
            
set { ViewState["SupportDir"= value; }
        }
        
//calendar是否显示时间
        [Bindable(true), Category("Behavior"), DefaultValue(false)]
        
public bool DisplayTime
        {
            
get { return (ViewState["DisplayTime"!= null ? (bool)ViewState["DisplayTime"] : false); }
            
set { ViewState["DisplayTime"= value; }
        }
        
//日期格式 
        [Browsable(false), Bindable(false)]
        
public string DateFormat
        {
            
get { return (ViewState["DateFormat"!= null ? (string)ViewState["DateFormat"] : ""); }
            
set { ViewState["DateFormat"= value; }
        }
        
//时间格式
        [Browsable(false), Bindable(false)]
        
public string TimeFormat
        {
            
get { return (ViewState["TimeFormat"!= null ? (string)ViewState["TimeFormat"] : ""); }
            
set { ViewState["TimeFormat"= value; }
        }
        
//默认选中的时间
        [Bindable(true), Category("Behavior")]
        
public DateTime SelectedDate
        {
            
get
            {
                EnsureChildControls();
                
if (this.Text.Length > 0)
                {
                    
try
                    {
                        
return DateTime.Parse(this.Text);
                    }
                    
catch (FormatException ex)
                    {
                        System.Diagnostics.Trace.WriteLine(
"Invalid datetime: " + this._dateTextBox.Text + " " + ex.Message, this.GetType().FullName);
                        
return DateTime.MinValue;
                    }
                }
                
else
                {
                    
return DateTime.MinValue;
                }
            }
            
set
            {
                EnsureChildControls();
                
this.Text = value.ToShortDateString();
                
if (this.DisplayTime)
                {
                    
this.Text += " " + value.ToShortTimeString();
                }
            }
        }

        
public override ControlCollection Controls
        {
            
get
            {
                EnsureChildControls();
                
return base.Controls;
            }
        }

        [TypeConverter(
typeof(UnitConverter))]
        
public override Unit Width
        {
            
get
            {
                EnsureChildControls();
                
return base.Width;
            }
            
set
            {
                EnsureChildControls();
                
base.Width = value;
                
this._dateTextBox.Width = Unit.Pixel((int)value.Value - 24);
            }
        }
        
#endregion

        
public event System.EventHandler DateChanged;

        
protected virtual void OnDateChanged(object sender)
        {
            
if (DateChanged != null)
            {
                DateChanged(sender, System.EventArgs.Empty);
            }
        }

        
public CalendarPicker()
        {
            
// 默认参数
            this.Theme = CalendarTheme.system;
            
this.SupportDir = "~/Support/JsCalendar";
            
this.DisplayTime = false;
            
this.DateFormat = ConvertDateFormat(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern);
            
this.TimeFormat = ConvertTimeFormat(CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern);
        }

        
protected override void CreateChildControls()
        {
            
this._dateTextBox = new TextBox();
            
this._calendarImage = new Image();

            
this._dateTextBox.EnableViewState = true;
            
this._dateTextBox.ID = "dateTextBox";
            
this._dateTextBox.ReadOnly = IsReadOnly;
            
this._dateTextBox.TextChanged += new EventHandler(DateTextBox_TextChanged);

            
this._calendarImage.EnableViewState = false;
            
this._calendarImage.ID = "trigger";
            
//日历小图标
            this._calendarImage.ImageUrl = GetClientFileUrl("cal.gif");
            
this._calendarImage.Attributes["align"= "top";
            
this._calendarImage.Attributes["hspace"= "4";

            Controls.Add(
this._dateTextBox);
            Controls.Add(
this._calendarImage);
        }

        
protected override void OnPreRender(EventArgs e)
        {
            
base.OnPreRender(e);
            
string themeCss = GetClientCssImport(String.Format("calendar-{0}.css"this.Theme.ToString().Replace("_""-")));
            Page.ClientScript.RegisterClientScriptBlock(
this.GetType(), "calendarcss", themeCss);

            
string calendarScripts = "";
            calendarScripts 
+= GetClientScriptInclude("calendar.js");
            calendarScripts 
+= GetClientScriptInclude("calendar-setup.js");
            
string languageFile = String.Format("lang/calendar-{0}.js"this.Language.ToString());
            calendarScripts 
+= GetClientScriptInclude(languageFile);
            Page.ClientScript.RegisterClientScriptBlock(
this.GetType(),"calendarscripts", calendarScripts);
            
string setupScript = GetCalendarSetupScript(this._dateTextBox.ClientID, GetFormatString(), this.ClientID);
            Page.ClientScript.RegisterStartupScript(
this.GetType(),this.ClientID + "script", setupScript);
        }
        
private string GetClientFileUrl(string fileName)
        {
            
return ResolveUrl(this.SupportDir + "/" + fileName);
        }
        
//引入js
        private string GetClientScriptInclude(string scriptFile)
        {
            
return "<script language=\"JavaScript\" src=\"" +
                GetClientFileUrl(scriptFile) + "\"></script>\n";
        }
        
//引入css
        private string GetClientCssImport(string fileName)
        {
            
return "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"" + GetClientFileUrl(fileName) + "\"/>";
        }
        
//为input添加Calendar
        private string GetCalendarSetupScript(string inputField, string format, string trigger)
        {
            StringBuilder sb 
= new StringBuilder();
            sb.Append(
"<script type=\"text/javascript\">Calendar.setup( { inputField : \"");
            sb.Append(inputField);
            sb.Append(
"\", ifFormat : \"");
            sb.Append(format);
            sb.Append(
"\", button : \"");
            sb.Append(trigger);
            sb.Append(
"\", showsTime : ");
            sb.Append(this.DisplayTime.ToString().ToLower());
            sb.Append(
" } ); </script>");
            
return sb.ToString();
        }
        
public string GetFormatString()
        {
            
if (this.DisplayTime)
            {
                
return this.DateFormat + " " + this.TimeFormat;
            }
            
else
            {
                
return this.DateFormat;
            }
        }
        
private void DateTextBox_TextChanged(object sender, EventArgs e)
        {
            OnDateChanged(sender);
        }
        
private string ConvertDateFormat(string shortDateFormat)
        {
            
string tempFormat = ReplaceFormatCharacter(shortDateFormat, "y""%Y");
            tempFormat 
= ReplaceFormatCharacter(tempFormat, "M""%m");
            tempFormat 
= ReplaceFormatCharacter(tempFormat, "d""%d");
            
return tempFormat;
        }
        
private string ConvertTimeFormat(string shortTimeFormat)
        {
            
string tempFormat = ReplaceFormatCharacter(shortTimeFormat, "H""%H");
            tempFormat 
= ReplaceFormatCharacter(tempFormat, "m""%M");
            tempFormat 
= ReplaceFormatCharacter(tempFormat, "h""%I");
            tempFormat 
= tempFormat.Replace("tt""%p");
            
return tempFormat;
        }
        
private string ReplaceFormatCharacter(string shortDateFormat, string from, string to)
        {
            
string pattern = from + "{1,4}";
            Regex regex 
= new Regex(pattern, RegexOptions.Compiled);
            
return regex.Replace(shortDateFormat, to);
        }
    }
    
//样式种类Created by jecray
    public enum CalendarTheme
    {
        aqua,
        blue,
        blue2,
        brown,
        green,
        win2k_1,
        win2k_2,
        win2k_cold_1,
        win2k_cold_2,
        system
    }
    
//语言种类 可以自定义添加
    public enum CalendarLanguage
    {
        en,
        zh
    }
}

使用方法:

需要设置SupportDir 放置js文件的地方 .
js calendar 在这里下载:http://prdownloads.sourceforge.net/jscalendar/jscalendar-1.0.zip?download
为了美观 , 在SupporDir下放个日历小图片 ,cal.gif.

有一点需要注意 文件编码要一致  注意js的编码
好了 大概就是这样.


posted @ 2007-08-20 01:25 jecray 阅读(1477) 评论(8) 编辑 收藏