大家好,欢迎来到我这里

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
一个基于JS日历的WebControl日历控件

using System;
using System.Web.UI.WebControls;
using System.Web;
using System.Web.UI;
using System.ComponentModel;

namespace PeoNormalControl
{
    //// <summary>
    /// JS类型的DateTimePicker   
    /// </summary>
    [
    ParseChildren(false)
    ]
    [
    ToolboxData("<{0}:DateTimePicker runat=server></{0}:DateTimePicker>"),DefaultEvent
("DateChanged"),ValidationProperty("DateText"),
    ]
    public class DateTimePicker:WebControl,IPostBackDataHandler
    {
        public DateTimePicker()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        private static object EventDateChangedObject;
        //public event EventHandler DateChanged;

       #region 数据成员

        private Int32 _Hour;
        private Int32 _Minute;
        private Int32 _Second;
       
        //// <summary>
        /// 设置或获取日期框文本。
        /// </summary>
        [Category("Data"),Description("设置或获取日期框文本。"),DefaultValue("")]
        public String DateText
        {
            get{           
                object objVal = ViewState["DateText"];
                return objVal == null ? String.Empty : objVal.ToString();
            }
            set{
                if (value.Length == 0)
                {                   
                    this.ViewState.SetItemDirty("DateText",false);
                    ViewState["DateText"] = String.Empty;
                    return;
                }
                ViewState["DateText"] = DateTime.Parse(value).ToString("yyyy-MM-dd");
            }
        }
        //// <summary>
        /// 设置或获取小时。
        /// </summary>
        [Category("Data"),Description("设置或获取小时。"),DefaultValue(0)]
        public Int32 Hour
        {
            get{return _Hour;}
            set{
                if (value > 23 || value < 0)
                    throw new ArgumentOutOfRangeException("Hour",value,"参数范围
溢出,小时的范围应在0-23之间。");
                _Hour = value;
            }
        }
        //// <summary>
        /// 设置或获取分钟。
        /// </summary>
        [Category("Data"),Description("设置或获取分钟。"),DefaultValue(0)]
        public Int32 Minute
        {
            get{return _Minute;}
            set{
                if (value > 59 || value < 0)
                    throw new ArgumentOutOfRangeException("Hour",value,"参数范围

溢出,分钟的范围应在0-59之间。");
                _Minute = value;
            }
        }
        //// <summary>
        /// 设置或获取秒钟。
        /// </summary>
        [Category("Data"),Description("设置或获取秒钟。"),DefaultValue(0)]
        public Int32 Second
        {
            get{return _Second;}
            set{
                if (value > 59 || value < 0)
                    throw new ArgumentOutOfRangeException("Hour",value,"参数范围

溢出,秒的范围应在0-59之间。");
                _Second = value;
            }
        }
        //// <summary>
        /// 设置或获取日期和时间。
        /// </summary>
        [Category("Data"),Description("设置或获取日期和时间。")]
        public DateTime SelectedDateTime
        {
            get{               
                return DateText == String.Empty ? DateTime.MinValue : DateTime.Parse

(DateText).AddHours(Hour).AddMinutes(Minute).AddSeconds(Second);
            }
            set
            {               
                if (value == DateTime.MinValue)
                {                   
                    this.DateText = String.Empty;
                    this.Hour = 0;
                    this.Minute = 0;
                    this.Second = 0;
                }
                else
                {                   
                    this.DateText = value.ToString("yyyy-MM-dd");
                    this.Hour = value.Hour;
                    this.Minute = value.Minute;
                    this.Second = value.Second;
                }
            }
        }
        #endregion

        #region 设置属性
       
        //// <summary>
        /// 日期改变后,是否自动回发服务器。
        /// </summary>
        [Category("Behavior"),Description("日期改变后,是否自动回发服务器。"),DefaultValue
(false),Bindable(false)]
        public bool AutoPostBack
        {
            get{
                object objVal = ViewState["AutoPostBack"];
                return objVal == null ? false : Convert.ToBoolean(objVal);
            }
            set{
                if (value == false)
                {
                    this.ViewState.SetItemDirty("AutoPostBack",false);            
                }

                ViewState["AutoPostBack"] = value;
            }
        }
        //// <summary>
        /// 是否允许用户提交空日期。
        /// </summary>
        [Category("Behavior"),Description("是否允许用户提交空日期。"),DefaultValue(false)]
        public bool AllowNull
        {
            get{
                object objVal = ViewState["AllowNull"];
                return objVal == null ? false : Convert.ToBoolean(objVal);
            }
            set{
                if (value == false)
                {
                    this.ViewState.SetItemDirty("AllowNull",false);           

       
                }

                ViewState["AllowNull"] = value;
            }
        }
        //// <summary>
        /// 是否显示时间部分。
        /// </summary>
        [Category("Behavior"),Description("是否显示时间部分。"),DefaultValue(false)]
        public bool ShowTime
        {
            get{
                object objVal = ViewState["ShowTime"];
                return objVal == null ? false : Convert.ToBoolean(objVal);
            }
            set{
                if (value == false)
                {
                    this.ViewState.SetItemDirty("ShowTime",false);           

       
                }

                ViewState["ShowTime"] = value;
            }
        }
        //// <summary>
        /// 日期为空时,是否自动填充当前日期和时间。
        /// </summary>
        [Category("Behavior"),Description("日期为空时,是否自动填充当前日期和时

间。"),DefaultValue(false)]
        public bool AutoFillNow
        {
            get{
                object objVal = ViewState["AutoFillNow"];
                return objVal == null ? false : Convert.ToBoolean(objVal);
            }
            set{
                if (value == false)
                {
                    this.ViewState.SetItemDirty("AutoFillNow",false);       

       
                }

                ViewState["AutoFillNow"] = value;
            }
        }
        //// <summary>
        /// 控件所需资源的路径。为空则先在程序目录下的“/js/”、“/calendar/”进行搜索,如果 ///不存在则调用程序集的内嵌资源。建议把所需资源放在以上两个目录中的一个,或放在任意目录中并设定此路径属性。
        //// </summary>
        [Description("控件所需资源的路径。"),DefaultValue(""),Bindable(false)]
        public string ResourcePath
        {
            get
            {
                object obj = ViewState["ResourcePath"];
                return (obj == null) ? String.Empty : Util.ResolveClientUrlSimple

(obj.ToString());
            }
            set
            {
                if (value == String.Empty)
                {
                    this.ViewState.SetItemDirty("ResourcePath",false);           
                }

                ViewState["ResourcePath"] = value;
            }
        }
        #endregion

        #region 事件
        //// <summary>
        /// 日期改变事件。
        /// </summary>
        [Category("Action"),Description("日期改变事件。")]
        public event EventHandler DateChanged
        {
            add
            {
                base.Events.AddHandler(EventDateChangedObject, value);
            }
            remove
            {
                base.Events.RemoveHandler(EventDateChangedObject, value);
            }
        }
        private void OnDateChanged(EventArgs e)
        {
            EventHandler handler1 = (EventHandler) base.Events[EventDateChangedObject];
            if (handler1 != null)
            {
                Page.Validate();

                handler1(this, e);
            }

        }
        #endregion

        #region 重写方法
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad (e);
            string strPath = this.ResourcePath == String.Empty ? "~/calendar/" :
this.ResourcePath;
            Util.RegisterGlobalClientScript(strPath,"calendar.js",this.Page);
            if (!Page.IsPostBack && this.Visible && this.AutoFillNow && this.DateText ==

String.Empty)
            {
                //对于自动填充时间要记住当前日期
                this.DateText = DateTime.Today.ToString("yyyy-MM-dd");
            }
        }

        public void RaisePostDataChangedEvent()
        {
            // TODO:  添加 DateTimePicker.RaisePostDataChangedEvent 实现
            this.OnDateChanged(EventArgs.Empty);
        }

        public bool LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
        {
            // TODO:  添加 DateTimePicker.LoadPostData 实现           
            string text1 = this.DateText;
            string text2 = postCollection[postDataKey];
            if (this.ShowTime)
            {
                string text3 = postCollection[postDataKey + "_Hour"];
                this.Hour = text3 == String.Empty ? 0 : Int32.Parse(text3);
                text3 = postCollection[postDataKey + "_Minute"];
                this.Minute = text3 == String.Empty ? 0 : Int32.Parse(text3);
                text3 = postCollection[postDataKey + "_Second"];
                this.Second = text3 == String.Empty ? 0 : Int32.Parse(text3);
            }
            if (text1.Length == 0 || text2.Length == 0)
            {
                if (!this.AllowNull && text2.Length == 0) throw new
NullReferenceException("控件" + this.ClientID + "的值不能为空");
                if (text1 != text2)
                {
                    this.DateText = text2;
                    return true;
                }
            }
            else if (!DateTime.Parse(text1).Equals(DateTime.Parse(text2)))
            {
                this.DateText = text2;
                return true;
            }
            return false;
        }
        protected override void EnsureChildControls()
        {
            if (!this.ChildControlsCreated)
            {
                base.EnsureChildControls ();
                if (!this.AllowNull)
                {
                    RequiredFieldValidator reqVal = new RequiredFieldValidator();
                    reqVal.ControlToValidate = this.ID;
                    reqVal.ID = this.ID + "_reqVal";
                    reqVal.CssClass = "CssError";
                    reqVal.ErrorMessage = "*";
                    reqVal.Display = ValidatorDisplay.Dynamic;
                    this.Controls.Add(reqVal);
                }
                CompareValidator cmpVal = new CompareValidator();
                cmpVal.ID = this.ID + "_cmpVal";
                cmpVal.ControlToValidate = this.ID;
                cmpVal.CssClass = "CssError";
                cmpVal.ErrorMessage = "日期格式错误";
                cmpVal.Display = ValidatorDisplay.Dynamic;
                cmpVal.Type = ValidationDataType.Date;
                cmpVal.Operator = ValidationCompareOperator.DataTypeCheck;
                this.Controls.Add(cmpVal);
                if (this.ShowTime)
                {
                    RangeValidator ragVal = new RangeValidator();
                    ragVal.ID = this.ClientID + "_Hour_ragVal";
                    ragVal.ControlToValidate = this.ClientID + "_Hour";
                    ragVal.CssClass = "CssError";
                    ragVal.ErrorMessage = "[0-23]";
                    ragVal.Type = ValidationDataType.Integer;
                    ragVal.MaximumValue = "23";
                    ragVal.MinimumValue = "0";
                    ragVal.Display = ValidatorDisplay.Dynamic;
                    this.Controls.Add(ragVal);

                    ragVal = new RangeValidator();
                    ragVal.ID = this.ClientID + "_Minute_ragVal";
                    ragVal.ControlToValidate = this.ClientID + "_Minute";
                    ragVal.CssClass = "CssError";
                    ragVal.ErrorMessage = "[0-59]";
                    ragVal.Type = ValidationDataType.Integer;
                    ragVal.MaximumValue = "59";
                    ragVal.MinimumValue = "0";
                    ragVal.Display = ValidatorDisplay.Dynamic;
                    this.Controls.Add(ragVal);

                    ragVal = new RangeValidator();
                    ragVal.ID = this.ClientID + "_Second_ragVal";
                    ragVal.ControlToValidate = this.ClientID + "_Second";
                    ragVal.CssClass = "CssError";
                    ragVal.ErrorMessage = "[0-59]";
                    ragVal.Type = ValidationDataType.Integer;
                    ragVal.MaximumValue = "59";
                    ragVal.MinimumValue = "0";
                    ragVal.Display = ValidatorDisplay.Dynamic;
                    this.Controls.Add(ragVal);

                    //伪控件
                    TextBox txt = new TextBox();
                    txt.ID = this.ClientID + "_Hour";
                    this.Controls.Add(txt);
                    txt = new TextBox();
                    txt.ID = this.ClientID + "_Minute";
                    this.Controls.Add(txt);
                    txt = new TextBox();
                    txt.ID = this.ClientID + "_Second";
                    this.Controls.Add(txt);
                }
                //this.ChildControlsCreated = true;
            }
        }
        protected override void OnPreRender(EventArgs e)
        {
            if ((this.Page != null) && this.Enabled)
            {
                this.Page.RegisterRequiresPostBack(this);
            }
        }
        private void RenderThis(HtmlTextWriter writer)
        {
            if (this.Page != null)
            {
                this.Page.VerifyRenderingInServerForm(this);
            }
            if (this.Visible)
            {               
                writer.Write("<input type=\"text\" name=\"{0}\" id=\"{0}
\"",this.ClientID);
                writer.Write(" style=\"width:78px\"");
                if (this.Enabled)
                {
                    if (this.AutoPostBack)
                        writer.Write(" onchange=\"javascript:{0}
\"",Util.GetClientValidatedPostback(this));
                }
                else writer.Write(" disabled");
                if (this.DateText == String.Empty && this.AutoFillNow && !
Page.IsPostBack) writer.Write(" value=\"{0}\"",DateTime.Today.ToString("yyyy-MM-dd"));
                else writer.Write(" value=\"{0}\"",this.DateText);
                writer.Write(" >");
                Control ctl;
                ctl = this.Controls[0];
                ctl.RenderControl(writer);
                int nTimeValidateCtlIndex = 1;
                if (!this.AllowNull)
                {
                    nTimeValidateCtlIndex++;
                    ctl = this.Controls[1];
                    ctl.RenderControl(writer);
                }
                if (this.Enabled) writer.Write("<a href=#none class=\"CssCalButton\"
onclick=\"javascript:calendar(document.all['{0}'])\">日历</a>",this.ClientID);
                if (this.ShowTime)
                {
                    writer.Write("&nbsp;<input type=\"text\" name=\"{0}\"

id=\"{0}\"",this.ClientID + "_Hour");
                    writer.Write(" style=\"width:22px\"");
                    if (!this.Enabled) writer.Write(" disabled");
                    if (this.Hour == 0 && this.AutoFillNow && !Page.IsPostBack)
writer.Write(" value=\"{0}\"",DateTime.Now.Hour);
                    else writer.Write(" value=\"{0}\"",this.Hour);
                    writer.Write(" >");
                    ctl = this.Controls[nTimeValidateCtlIndex];
                    ctl.RenderControl(writer);
                    nTimeValidateCtlIndex++;
                    writer.Write("<span class=\"{0}\">时</span>",this.CssClass);
                    writer.Write("<input type=\"text\" name=\"{0}\" id=\"{0}
\"",this.ClientID + "_Minute");
                    writer.Write(" style=\"width:22px\"");
                    if (!this.Enabled) writer.Write(" disabled");
                    if (this.Minute == 0 && this.AutoFillNow && !Page.IsPostBack)
writer.Write(" value=\"{0}\"",DateTime.Now.Minute);
                    else writer.Write(" value=\"{0}\"",this.Minute);
                    writer.Write(" >");
                    ctl = this.Controls[nTimeValidateCtlIndex];
                    ctl.RenderControl(writer);
                    nTimeValidateCtlIndex++;
                    writer.Write("<span class=\"{0}\">分</span>",this.CssClass);
                    writer.Write("<input type=\"text\" name=\"{0}\" id=\"{0}
\"",this.ClientID + "_Second");
                    writer.Write(" style=\"width:22px\"");
                    if (!this.Enabled) writer.Write(" disabled");
                    if (this.Second == 0 && this.AutoFillNow && !Page.IsPostBack)
writer.Write(" value=\"{0}\"",DateTime.Now.Second);
                    else writer.Write(" value=\"{0}\"",this.Second);
                    writer.Write(" >");
                    ctl = this.Controls[nTimeValidateCtlIndex];
                    ctl.RenderControl(writer);
                    writer.Write("<span class=\"{0}\">秒</span>",this.CssClass);
                }
            }
        }
        protected override void Render(HtmlTextWriter writer)
        {
            RenderThis(writer);
            //base.Render (writer);
        }

        #endregion
    }
    internal sealed class Util
    {
        private Util()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        internal static String ResolveClientUrlSimple(string relativeUrl)
        {

            if (relativeUrl == null)
            {
                throw new ArgumentNullException("relativeUrl");
            }
            if (relativeUrl.Length == 0) return relativeUrl;
            if (relativeUrl.StartsWith("~"))
            {
                string text1 = HttpContext.Current.Request.ApplicationPath;
                if (text1.Length == 0)
                {
                    return relativeUrl;
                }
                return text1+relativeUrl.TrimStart('~');
            }
            return relativeUrl;
        }
        internal static string GetClientValidatedPostback(Control control)
        {
            string text1 = control.Page.GetPostBackEventReference(control);
            return ("{if (typeof(Page_ClientValidate) != 'function' ||  Page_ClientValidate()) " + text1 + "} ");
        }
        internal static void RegisterGlobalClientScript(string sDefaultPath, string sScriptFile,Page oPage)
        {
            string sInstanceId = sScriptFile;
            if(oPage.IsClientScriptBlockRegistered(sInstanceId)) return;
            string sScript = string.Empty;       
            sDefaultPath = ResolveClientUrlSimple(sDefaultPath);
            try
            {
                string sStandardRootClientScriptPath = Path.Combine(sDefaultPath,  sScriptFile).Replace("\\", "/");

                if(File.Exists(HttpContext.Current.Server.MapPath(sStandardRootClientScriptPath)))
                {
                    sScript = "<script language=\"javascript\" src=\"" + sStandardRootClientScriptPath + "\" type=\"text/javascript\"></script>";
                }
            }
            catch {}
               
            if(sScript == string.Empty)
            {
                try
                {
                    string sAppRootClientScriptPath = Path.Combine(Path.Combine(HttpContext.Current.Request.ApplicationPath, "js"),  sScriptFile).Replace("\\", "/");

                    if(File.Exists(HttpContext.Current.Server.MapPath(sAppRootClientScriptPath)))
                    {
                        sScript = "<script language=\"javascript\" src=\"" + sAppRootClientScriptPath + "\" type=\"text/javascript\"></script>";
                    }
                }
                catch {}
            }
       
            // If everything failed, emit our internal script
            if(sScript == string.Empty)
            {
                sScript = DemarcateClientScript(GetResourceContent(Assembly.GetExecutingAssembly().GetName().Name + "." + sScriptFile));
            }           
       

            oPage.RegisterClientScriptBlock(sInstanceId, sScript);           
        }
        internal static string GetResourceContent(string sFileName)
        {
            Stream oStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(sFileName);
            if (oStream == null) throw new FileNotFoundException("内嵌资源未找到。",sFileName);
            StreamReader oReader = new StreamReader(oStream);
         
            return oReader.ReadToEnd();
        }
        internal static string DemarcateClientScript(string script)
        {
            return DemarcateClientScript(script, null);
        }
        internal static string DemarcateClientScript(string script, string title)
        {
            StringBuilder result = new StringBuilder();
            result.Append("<script language=\"javascript\" type=\"text/javascript\">\n");
            result.Append("//<![CDATA[\n");
            if (title != null)
            {
                result.Append("* "); result.Append(title); result.Append(" ***/\n");
            }
            result.Append(script);
            result.Append("\n");
            result.Append("//]]>\n");
            result.Append("</script>\n");
            return result.ToString();
        }
    }
  }

posted on 2007-04-09 08:09  zwgood  阅读(804)  评论(0编辑  收藏  举报