TDateEditPicker: A Nullable & Bindingable Date Edit and Pick Control

TDateEditPicker: A Nullable & Bindingable Date Edit and Pick Control_第1张图片TDateEditPicker: A Nullable & Bindingable Date Edit and Pick Control_第2张图片

TDateEditPicker is a .net 2.0 windows form control which is derived from TextBox and DateTimePicker, it's main features are:

  • Date can be nullable and bindingable.(ver1.3)
  • Can set the edit box ForeColor and BackColor.
  • Can set the error date ForeColor.
  • Click/Enter selects a date.
  • ESC/Click outside control abandons the current select.
  • Can set initiate date when at design mode.(ver1.5)
  • Can set date show format(yyyymmdd/mmddyy/ddmmyyyy).
  • Can set date seperator.

 Below are the source codes of TDateEditPicer(Ver 1.3): TDateEditPicker Demo and Sources, Ver1.5: TDateEditPicker Demo and Source.,Ver1.6: TDateEditPicker Demo and Source。Ver1.8: TDateEditPicker Demo and Source. Version1.9(2010-4-8)。Version1.11(2010-4-17)。

 

using System; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; using System.Text.RegularExpressions; namespace CSUST.Data { [ToolboxItem(false)] public class TDateEditBox : TextBox { private const int MaxTextLength = 10; // 固定10个字符 private char[] textChars = new char[] { ' ', ' ', ' ', ' ', '-', ' ', ' ', '-', ' ', ' ' }; private char[] lastErrorTextChars = new char[MaxTextLength]; private char dateSeperator = '-'; // 分隔 private int minDateYear = 1950; private int maxDateYear = 2060; private bool isNull = true; private bool isValid = false; private Color validDateForeColor; private Color errorDateForeColor = Color.Red; private DateTime date; public event EventHandler EditBoxDateChanged; public TDateEditBox() { base.MaxLength = MaxTextLength; this.ContextMenu = new ContextMenu(); validDateForeColor = base.ForeColor; this.SetToNullDate(); } public new int MaxLength { get { return base.MaxLength; } set { base.MaxLength = MaxTextLength; } } public int MinDateYear { get { return minDateYear; } set { minDateYear = value; } } public int MaxDateYear { get { return maxDateYear; } set { maxDateYear = value; } } public Color ErrorDateForeColor { get { return errorDateForeColor; } set { errorDateForeColor = value; if (isValid == false && isNull == false) { this.ShowErrorDateColor(); } } } public override Color ForeColor { get { return base.ForeColor; } set { if (value != errorDateForeColor) { base.ForeColor = value; validDateForeColor = value; } if (isNull == true || isValid == true) { this.ShowValidDateColor(); } } } public char DateSeperator { get { return dateSeperator; } set { if (value != '-' && value != '/' && value != '.') { dateSeperator = '-'; } else { dateSeperator = value; } textChars[4] = dateSeperator; textChars[7] = dateSeperator; this.ShowDateText(); base.SelectionStart = 0; } } public bool IsNull { get { return isNull; } } public bool IsValid { get { return isValid; } } public object Date { get { if (isNull == true || isValid == false) { return null; } return date; } set { if (value == null || value == DBNull.Value) { this.SetToNullDate(); } else { date = (DateTime)value; this.SetToGiveDate(date); } if (base.ForeColor != validDateForeColor) { base.ForeColor = validDateForeColor; } this.Invalidate(); } } public void OnEditBoxDateChanged() { if (isValid == true || isNull == true) { if (this.EditBoxDateChanged != null) { this.EditBoxDateChanged(this, EventArgs.Empty); } } } protected override void OnKeyDown(KeyEventArgs e) { if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift && (e.KeyCode == Keys.Right) || e.KeyCode == Keys.Left || e.KeyCode == Keys.Home || e.KeyCode == Keys.End) { base.OnKeyDown(e); return; } if (e.KeyData == Keys.Tab || e.KeyData == Keys.Home || e.KeyData == Keys.End) { base.OnKeyDown(e); return; } if (e.KeyCode == Keys.Back) { this.KeyBackSpace(); } else if (e.KeyCode == Keys.Delete) { this.KeyDelete(); } else if (e.KeyData == Keys.Left) { this.MoveLeft(); } else if (e.KeyData == Keys.Right) { this.MoveRight(); } else if ((e.KeyValue >= '0' && e.KeyValue <= '9') || e.KeyValue == ' ') { this.KeyDigit(e.KeyValue); } else if ((e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)) { int keyValue = (int)e.KeyCode - (int)Keys.NumPad0 + (int)Keys.D0; this.KeyDigit(keyValue); } e.SuppressKeyPress = true; e.Handled = true; this.ParseDateText(); } protected override void OnLeave(EventArgs e) { this.NormalizeDateText(); base.OnLeave(e); } protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); base.SelectionLength = 0; } private void SetToNullDate() { textChars[0] = ' '; textChars[1] = ' '; textChars[2] = ' '; textChars[3] = ' '; textChars[4] = dateSeperator; textChars[5] = ' '; textChars[6] = ' '; textChars[7] = dateSeperator; textChars[8] = ' '; textChars[9] = ' '; isNull = true; isValid = false; this.ShowDateText(); base.SelectionStart = 0; } private void SetToGiveDate(DateTime date) { string today = date.ToString("yyyy-MM-dd"); for (int k = 0; k < today.Length; k++) { if (k != 4 && k != 7) { textChars[k] = today[k]; } } isNull = false; isValid = true; this.ShowDateText(); base.SelectionStart = 0; } private void SaveAsLastErrorText() { if (isNull == true) { return; } for (int k = 0; k < textChars.Length; k++) { lastErrorTextChars[k] = textChars[k]; } } private void ParseDateText() { string y = new string(textChars, 0, 4); string m = new string(textChars, 5, 2); string d = new string(textChars, 8, 2); string yy = y.Trim(); string mm = m.Trim(); string dd = d.Trim(); if (string.IsNullOrEmpty(yy) == true && string.IsNullOrEmpty(mm) == true && string.IsNullOrEmpty(dd) == true) { bool preIsNull = isNull; isNull = true; isValid = false; if (preIsNull != isNull) { this.ShowValidDateColor(); this.OnEditBoxDateChanged(); } return; } isNull = false; if (string.IsNullOrEmpty(yy) == true || string.IsNullOrEmpty(mm) == true || string.IsNullOrEmpty(dd) == true) { isValid = false; this.SaveAsLastErrorText(); this.ShowErrorDateColor(); return; } if (Regex.IsMatch(yy, @"/d{4}") == false || Regex.IsMatch(mm, @"/d{1,2}") == false || Regex.IsMatch(dd, @"/d{1,2}") == false) { isValid = false; this.SaveAsLastErrorText(); this.ShowErrorDateColor(); return; } int year = int.Parse(yy); int month = int.Parse(mm); int day = int.Parse(dd); if (year < minDateYear || year > maxDateYear || month < 1 || month > 12 || day < 1 || day > DateTime.DaysInMonth(year, month)) { isValid = false; this.SaveAsLastErrorText(); this.ShowErrorDateColor(); return; } isValid = true; this.ShowValidDateColor(); bool modified = false; if (year != date.Year || month != date.Month || day != date.Day) { modified = true; } date = new DateTime(year, month, day); if (modified == true) { this.OnEditBoxDateChanged(); } } private void NormalizeDateText() { if (isValid == false || isNull == true) { return; } if (textChars[5] == ' ' || textChars[6] == ' ' || textChars[8] == ' ' || textChars[9] == ' ') { if (textChars[5] == ' ') { textChars[5] = '0'; } if (textChars[6] == ' ') { textChars[6] = textChars[5]; textChars[5] = '0'; } if (textChars[8] == ' ') { textChars[8] = '0'; } if (textChars[9] == ' ') { textChars[9] = textChars[8]; textChars[8] = '0'; } ShowDateText(); } } private void ShowDateText() { if (isNull == false && isValid == false) { if (base.ForeColor != errorDateForeColor) { base.ForeColor = errorDateForeColor; } } else { if (base.ForeColor != validDateForeColor) { base.ForeColor = validDateForeColor; } } base.Text = new string(textChars); } private void ShowValidDateColor() { if (base.ForeColor != validDateForeColor) { base.ForeColor = validDateForeColor; } this.Invalidate(); } private void ShowErrorDateColor() { if (base.ForeColor != errorDateForeColor) { base.ForeColor = errorDateForeColor; } this.Invalidate(); } public void ResumeLastErrorText() { for (int k = 0; k < textChars.Length; k++) { textChars[k] = lastErrorTextChars[k]; } if (base.ForeColor != errorDateForeColor) { base.ForeColor = errorDateForeColor; } isValid = false; base.Text = new string(textChars); this.OnEditBoxDateChanged(); } private void KeyDelete() { if (base.SelectionLength <= 1) { this.KeyDelete(base.SelectionStart); } else { int start = base.SelectionStart + base.SelectionLength; int end = base.SelectionStart + 1; for (int k = start; k >= end; k--) { KeyBackSpace(k); } } } private void KeyDelete(int selectionStart) { if (AtTextEnd(selectionStart) == true) { return; } this.KeyBackSpace(selectionStart + 1); } private void KeyBackSpace() { this.KeyBackSpace(base.SelectionStart); } private void KeyBackSpace(int selectionStart) { int curPos = selectionStart; if (curPos == 0) { return; } if (AtSeperatorRight(curPos) == true) { base.SelectionStart = curPos - 1; return; } if (AtTextEnd(curPos) == true) { textChars[textChars.Length - 1] = ' '; ShowDateText(); base.SelectionStart = curPos - 1; return; } if (AtSeperatorLeft(curPos) == true) { textChars[curPos - 1] = ' '; ShowDateText(); base.SelectionStart = curPos - 1; return; } int k = curPos; while (AtSeperatorLeft(k) == false && AtTextEnd(k) == false) { textChars[k - 1] = textChars[k]; k++; } textChars[k - 1] = ' '; ShowDateText(); base.SelectionStart = curPos - 1; } private void KeyDigit(int keyValue) { if (AtTextEnd() == true) { return; } int curPos = base.SelectionStart; int newPos = curPos; if (AtSeperatorLeft() == true) { textChars[base.SelectionStart + 1] = (char)keyValue; newPos = curPos + 2; } else if (AtSeperatorLeft(curPos + 1) == true) { textChars[base.SelectionStart] = (char)keyValue; newPos = curPos + 2; } else { textChars[base.SelectionStart] = (char)keyValue; if (AtSeperatorRight(curPos + 1) == true) { curPos++; } newPos = curPos + 1; } this.ShowDateText(); base.SelectionStart = newPos; } private void MoveLeft() { if (base.SelectionStart == 0) { return; } if (AtSeperatorRight(base.SelectionStart) == true) { base.SelectionStart -= 2; } else { base.SelectionStart -= 1; } } private void MoveRight() { if (this.AtTextEnd() == true) { return; } if (AtSeperatorLeft(base.SelectionStart + 1) == true) { base.SelectionStart += 2; } else { base.SelectionStart += 1; } } private bool AtSeperatorLeft(int curPos) { if (curPos == 4 || curPos == 7) { return true; } return false; } private bool AtSeperatorLeft() { return AtSeperatorLeft(base.SelectionStart); } private bool AtSeperatorRight(int curPos) { if (curPos == 5 || curPos == 8) { return true; } return false; } private bool AtSeperatorRight() { return AtSeperatorRight(base.SelectionStart); } private bool AtTextEnd(int curPos) { if (curPos == textChars.Length) { return true; } return false; } private bool AtTextEnd() { return AtTextEnd(base.SelectionStart); } } [ToolboxItem(false)] public class TDatePicker : DateTimePicker { private bool isDropdown = false; private DateTime dateBeforeDropDown; private const int WM_IME_SETCONTENT = 0x0281; private const int WM_CAPTURECHANGED = 0x0215; private const int WM_KEY_DOWN = 0x100; private const int WM_KEY_UP = 0x101; private const int WM_KEY_ENTER = 0x000d; private const int WM_KEY_ESC = 0x001b; private bool msgHandledAfterCloseup = true; protected bool msgHandledByImeSetContent = false; public event EventHandler DateConfirmed; public event EventHandler DateAbandoned; protected override void OnDropDown(EventArgs eventargs) { msgHandledAfterCloseup = true; isDropdown = true; dateBeforeDropDown = this.Value.Date; base.OnDropDown(eventargs); } protected override void OnCloseUp(EventArgs eventargs) { isDropdown = false; msgHandledAfterCloseup = false; msgHandledByImeSetContent = false; base.OnCloseUp(eventargs); } protected override void OnKeyDown(KeyEventArgs e) { if (isDropdown == true && (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Home || e.KeyCode == Keys.End || e.KeyCode == Keys.PageUp || e.KeyCode == Keys.PageDown)) { base.OnKeyDown(e); // 不需要捕获 ESC/Enter 健 } else { e.SuppressKeyPress = true; e.Handled = true; } } private void OnDateConfirmed() { if (this.DateConfirmed != null) { this.DateConfirmed(this, EventArgs.Empty); } } private void OnDateAbandoned() { if (this.Value.Date != dateBeforeDropDown) { this.Value = dateBeforeDropDown; } if (this.DateConfirmed != null) { this.DateAbandoned(this, EventArgs.Empty); } } protected override void WndProc(ref Message m) { if (msgHandledAfterCloseup == false && m.Msg == WM_CAPTURECHANGED) { msgHandledAfterCloseup = true; msgHandledByImeSetContent = false; this.OnDateAbandoned(); } else if (msgHandledAfterCloseup == false && m.Msg == WM_KEY_UP && m.WParam.ToInt32() == WM_KEY_ENTER) { msgHandledAfterCloseup = true; msgHandledByImeSetContent = false; this.OnDateConfirmed(); } else if ((msgHandledAfterCloseup == false || msgHandledByImeSetContent == true) && (m.Msg == WM_KEY_UP && m.WParam.ToInt32() == WM_KEY_ESC)) { msgHandledAfterCloseup = true; msgHandledByImeSetContent = false; this.OnDateAbandoned(); } else if (msgHandledAfterCloseup == false && m.Msg == WM_IME_SETCONTENT) { msgHandledAfterCloseup = true; msgHandledByImeSetContent = true; this.OnDateConfirmed(); } if (m.Msg == WM_KEY_DOWN) // keydown { msgHandledByImeSetContent = false; } base.WndProc(ref m); } } public class TDateEditPicker : UserControl, INotifyPropertyChanged { private IContainer components = null; private const int MINDATEYEAR = 1949; private const int MAXDATEYEAR = 2100; private TDateEditBox dateEditBox; private TDatePicker datePicker; private bool isNullWhenDropDown; private bool isValidWhenDropDown; private string version = "1.3"; private int nativeEditBoxWidth; public event PropertyChangedEventHandler PropertyChanged; public TDateEditPicker() { this.InitializeComponent(); this.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.Never; // 强制默认方式 this.dateEditBox.Leave += new EventHandler(this.DateEditBox_Leave); this.datePicker.DropDown += new EventHandler(this.DateTimePicker_DropDown); this.dateEditBox.EditBoxDateChanged += new EventHandler(this.DateEditBox_DateChanged); this.datePicker.DateConfirmed += new EventHandler(this.DateTimePicker_DataConfirmed); this.datePicker.DateAbandoned += new EventHandler(this.DateTimePicker_DateAbandoned); } private void InitializeComponent() { this.dateEditBox = new TDateEditBox(); this.datePicker = new TDatePicker(); this.SuspendLayout(); this.datePicker.Location = new Point(1, 0); this.datePicker.Name = "datePicker"; this.datePicker.Value = DateTime.Now; this.datePicker.MinDate = new DateTime(this.dateEditBox.MinDateYear, 1, 1); this.datePicker.MaxDate = new DateTime(this.dateEditBox.MaxDateYear, 12, 31); this.datePicker.Format = DateTimePickerFormat.Custom; this.datePicker.CustomFormat = " "; this.dateEditBox.Location = new Point(0, 0); this.dateEditBox.Name = "dateEditBox"; this.nativeEditBoxWidth = this.dateEditBox.Height; this.Controls.Add(this.datePicker); this.Controls.Add(this.dateEditBox); this.Name = "TDateEditPicker"; this.Size = new Size(this.datePicker.Width + 2, this.dateEditBox.Height + 2); this.dateEditBox.BringToFront(); this.ResumeLayout(); } protected override void Dispose(bool disposing) { if (disposing == true) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } protected override void OnResize(EventArgs e) { base.OnResize(e); int adjustWidth = 2; if (this.BorderStyle == BorderStyle.Fixed3D) { adjustWidth = 3; } this.datePicker.Width = this.Width - adjustWidth; this.dateEditBox.Width = this.datePicker.Width - this.nativeEditBoxWidth + 2; } private void DateEditBox_Leave(object sender, EventArgs e) { if (this.IsValid == true && this.IsNull == false) { this.datePicker.Value = (DateTime)dateEditBox.Date; } else { this.datePicker.Value = DateTime.Now.Date; } } private void DateEditBox_DateChanged(object sender, EventArgs e) { if (this.IsNull == true || this.IsValid == true) { this.NotifyPropertyChanged("Date"); } } private void DateTimePicker_DropDown(object sender, EventArgs e) { isNullWhenDropDown = this.IsNull; isValidWhenDropDown = this.IsValid; } private void DateTimePicker_DataConfirmed(object sender, EventArgs e) { this.dateEditBox.Date = this.datePicker.Value.Date; this.NotifyPropertyChanged("Date"); } private void DateTimePicker_DateAbandoned(object sender, EventArgs e) { if (isNullWhenDropDown == true) { this.dateEditBox.Date = null; } else if (isValidWhenDropDown == false) { this.dateEditBox.ResumeLastErrorText(); } } private void NotifyPropertyChanged(string info) { if (this.DataBindings != null && this.DataBindings.Count > 0) { if (this.DataBindings[0].DataSourceUpdateMode == DataSourceUpdateMode.OnValidation) // == never { return; } } if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(info)); } } [Category("Custom")] public string Version { get { return version; } } [Category("Custom"), DefaultValue('-')] [Description("Set date seperator, only -./ threes.")] public char DateSeperator { get { return dateEditBox.DateSeperator; } set { dateEditBox.DateSeperator = value; } } [Category("Custom"), DefaultValue(1950)] [Description("Set the min valid date year.")] public int MinDateYear { get { return this.dateEditBox.MinDateYear; } set { int tmpValue = value; if (tmpValue < MINDATEYEAR || tmpValue > MAXDATEYEAR) { tmpValue = MINDATEYEAR; } if (this.MinDateYear != tmpValue) { this.dateEditBox.MinDateYear = tmpValue; this.datePicker.MinDate = new DateTime(tmpValue, 1, 1); } } } [Category("Custom"),DefaultValue(2060)] [Description("Set the max valid date year.")] public int MaxDateYear { get { return this.dateEditBox.MaxDateYear; } set { int tmpValue = value; if (tmpValue < MINDATEYEAR || tmpValue > MAXDATEYEAR) { tmpValue = MAXDATEYEAR; } else { this.dateEditBox.MaxDateYear = tmpValue; this.datePicker.MaxDate = new DateTime(tmpValue, 12, 31); } } } [Category("Custom")] [Description("Is the date is null.")] public bool IsNull { get { return dateEditBox.IsNull; } } [Category("Custom")] [Description("Is the date is valid.")] public bool IsValid { get { return dateEditBox.IsValid; } } [Bindable(true), Browsable(false)] public Object Date { get { return this.dateEditBox.Date; } set { this.dateEditBox.Date = value; this.NotifyPropertyChanged("Date"); } } [Category("Custom"), DefaultValue(typeof(Color), "Red")] [Description("Set the error date ForeColor.")] public Color DateErrorForeColor { get { return this.dateEditBox.ErrorDateForeColor; } set { this.dateEditBox.ErrorDateForeColor = value; } } [Category("Custom"), DefaultValue(true)] [Description("Is the date picker enabled.")] public bool DatePickerEnabled { get { return datePicker.Enabled; } set { datePicker.Enabled = value; } } [Category("Custom"), DefaultValue(true)] [Description("Is the date picker visible.")] public bool DatePickerVisible { get { return datePicker.Visible; } set { datePicker.Visible = value; } } [Category("Custom")] public Font CalendarFont { get { return datePicker.CalendarFont; } set { datePicker.CalendarFont = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "ControlText")] public Color CalendarForeColor { get { return datePicker.CalendarForeColor; } set { datePicker.CalendarForeColor = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "Window")] public Color CalendarMonthBackColor { get { return datePicker.CalendarMonthBackground; } set { datePicker.CalendarMonthBackground = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "ActiveCaption")] public Color CalendarTitleForeColor { get { return datePicker.CalendarTitleForeColor; } set { datePicker.CalendarTitleForeColor = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "ActiveCaptionText")] public Color CalendarTitleBackColor { get { return datePicker.CalendarTitleBackColor; } set { datePicker.CalendarTitleBackColor = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "GrayText")] public Color CalendarTrailingForeColor { get { return datePicker.CalendarTrailingForeColor; } set { datePicker.CalendarTrailingForeColor = value; } } [Category("Custom")] [DefaultValue(typeof(Color), "WindowText")] [Description("Set the valid date ForeColor.")] public Color DateTextForeColor { get { return dateEditBox.ForeColor; } set { dateEditBox.ForeColor = value; } } [Browsable(false)] public new Color ForeColor { get { return base.ForeColor; } set { } } [Category("Custom")] [DefaultValue(typeof(Color), "Window")] [Description("Set the date edit box BackColor.")] public Color DateBoxBackColor { get { return dateEditBox.BackColor; } set { dateEditBox.BackColor = value; } } [Browsable(false)] public new Color BackColor { get { return base.BackColor; } set { } } } }

 

你可能感兴趣的:(Date,object,String,null,dropdown,Components)