#if FRAMEWORK20 using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Globalization; using System.Collections; using System.Net; using DevComponents.DotNetBar; using System.Drawing; using System.Windows.Forms; namespace DevComponents.Editors.DateTimeAdv { [ToolboxBitmap(typeof(DotNetBarManager), "DateTimeInput.ico"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.DateTimeInputDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf")] [DefaultBindingProperty("ValueObject"), DefaultProperty("ValueObject")] public class DateTimeInput : VisualControlBase, ICommandSource { #region Private Variables private DateTimeGroup _DateInputGroup = null; private ButtonItem _PopupItem = null; private MonthCalendarItem _MonthCalendar = null; private TimeSelectorItem _TimeSelector = null; private LabelItem _Spacer = null; #endregion #region Events /// /// Occurs when the Value or IsEmpty property changes. /// /// This event is not raised when the entered date is earlier than MinDateTime or later than MaxDateTime. /// /// public event EventHandler ValueChanged; /// /// Occurs when the Value or IsEmpty property changes. This event occurs at the same time and has same function as ValueChanged event. It is provided for binding support. /// public event EventHandler ValueObjectChanged; /// /// Occurs when the Format property value has changed. /// public event EventHandler FormatChanged; /// /// Occurs when Clear button is clicked and allows you to cancel the default action performed by the button. /// public event CancelEventHandler ButtonClearClick; /// /// Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup. /// public event CancelEventHandler ButtonDropDownClick; /// /// Occurs when ValueObject property is set and it allows you to provide custom parsing for the values. /// public event ParseDateTimeValueEventHandler ParseValue; /// /// Occurs when ShowCheckBox property is set to true and user changes the lock status of the control by clicking the check-box. /// public event EventHandler LockUpdateChanged; #endregion #region Constructor /// /// Initializes a new instance of the DateTimeInput class. /// public DateTimeInput() { } #endregion #region Internal Implementation /// /// Copies the current value in the control to the Clipboard. /// public virtual void Copy() { if (_DateInputGroup != null) Clipboard.SetText(this.Text); } /// /// Pastes the current Clipboard content if possible as the value into the control. /// public virtual void Paste() { if (_DateInputGroup != null) Text = Clipboard.GetText(); } /// /// Moves the current control value to the Clipboard. /// public virtual void Cut() { if (_DateInputGroup != null) { Copy(); if(this.AllowEmptyState) ValueObject = null; } } protected override PopupItem CreatePopupItem() { ButtonItem button = new ButtonItem("sysPopupProvider"); button.PopupClose += new EventHandler(DropDownPopupClose); ItemContainer container = new ItemContainer(); container.LayoutOrientation = eOrientation.Horizontal; container.BackgroundStyle.Padding = 4; MonthCalendarItem mc = new MonthCalendarItem(); mc.CalendarDimensions = new Size(1, 1); //mc.DayClickAutoClosePopup = false; //mc.BackgroundStyle.BackColor = SystemColors.Window; mc.DateChanged += new EventHandler(PopupSelectedDateChanged); container.SubItems.Add(mc); button.SubItems.Add(container); LabelItem sep = new LabelItem(); sep.Width = 8; sep.AutoCollapseOnClick = false; sep.Visible = false; container.SubItems.Add(sep); TimeSelectorItem timeSelector = new TimeSelectorItem(); timeSelector.SelectorType = _TimeSelectorType; timeSelector.SelectedTimeChanged += new EventHandler(TimeSelectorChanged); timeSelector.TimeFormat = _TimeSelectorTimeFormat; timeSelector.Visible = false; container.SubItems.Add(timeSelector); _PopupItem = button; _MonthCalendar = mc; _TimeSelector = timeSelector; _Spacer = sep; UpdateTimeSelectorItemSize(); return button; } protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); _PopupItem.NotifyScaleItem(factor); UpdateTimeSelectorItemSize(); } private void UpdateTimeSelectorItemSize() { if (_TimeSelector == null) return; _TimeSelector.HourMinuteButtonSize = new Size(_TimeSelector.HourMinuteButtonSize.Width, this.Font.Height <= 15 ? 15 : Dpi.DescaleHeight(this.Font.Height) + 1); } protected override void OnFontChanged(EventArgs e) { UpdateTimeSelectorItemSize(); base.OnFontChanged(e); } /// /// Gets whether popup calendar is open. /// [Browsable(false)] public bool IsPopupCalendarOpen { get { return _PopupItem.Expanded; } set { if (_PopupItem.Expanded != value) ToggleCalendarPopup(); } } private bool _PopupCalendarKeyboardNavigationEnabled = true; /// /// Gets or sets whether selected date on popup calendar can be changed using keyboard arrow keys. /// [Browsable(false), DefaultValue(true)] public bool PopupCalendarKeyboardNavigationEnabled { get { return _PopupCalendarKeyboardNavigationEnabled; } set { _PopupCalendarKeyboardNavigationEnabled = value; } } protected override bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { if (IsPopupCalendarOpen) { int days = 0; int wParamInt = WinApi.ToInt(wParam); if (_PopupCalendarKeyboardNavigationEnabled) { if (wParamInt == 37) // Left Arrow days = -1; else if (wParamInt == 39) // Right Arrow days = 1; else if (wParamInt == 40) // Down Arrow days = 7; else if (wParamInt == 38) // Up Arrow days = -7; } else if (wParamInt == 13 && _MonthCalendar.SelectedDate != DateTime.MinValue) // Enter { ToggleCalendarPopup(); return true; } if (days != 0) { if (_MonthCalendar.SelectedDate == DateTime.MinValue) _MonthCalendar.SelectedDate = DateTime.Today; else _MonthCalendar.SelectedDate = _MonthCalendar.SelectedDate.AddDays(days); if (_MonthCalendar.DisplayMonth.Month != _MonthCalendar.SelectedDate.Month) _MonthCalendar.DisplayMonth = _MonthCalendar.SelectedDate; return true; } } return base.OnKeyDown(hWnd, wParam, lParam); } /// /// Gets or sets the default date-time values that are used by the control. /// public static DateTime DateTimeDefaults = DateTime.Today; private void TimeSelectorChanged(object sender, EventArgs e) { DateTime date = this.Value; if (date == DateTime.MinValue) date = DateTimeDefaults; if (date != DateTime.MinValue && date != DateTime.MaxValue) date = new DateTime(date.Year, date.Month, date.Day, _TimeSelector.SelectedTime.Hours, _TimeSelector.SelectedTime.Minutes, _TimeSelector.SelectedTime.Seconds); if (this.MinDate != DateTime.MinValue && date < this.MinDate) date = this.MinDate; _DateInputGroup.Value = date; } private void PopupSelectedDateChanged(object sender, EventArgs e) { if (_MonthCalendar.SelectedDate == DateTime.MinValue) this.IsEmpty = true; else { DateTime date = _MonthCalendar.SelectedDate; DateTime value = this.Value; if (value != DateTime.MinValue && value != DateTime.MaxValue) date = new DateTime(date.Year, date.Month, date.Day, value.Hour, value.Minute, value.Second); if (this.MinDate != DateTime.MinValue && date < this.MinDate) date = this.MinDate; _DateInputGroup.Value = date; } } protected override VisualItem CreateRootVisual() { _ButtonClear = new InputButtonSettings(this); _ButtonDropDown = new InputButtonSettings(this); _ButtonFreeText = new InputButtonSettings(this); _DateInputGroup = new DateTimeGroup(); _DateInputGroup.IsRootVisual = true; _DateInputGroup.ValueChanged += new EventHandler(InputGroup_ValueChanged); FormatToDateTimeGroup(); return _DateInputGroup; } private void InputGroup_ValueChanged(object sender, EventArgs e) { if (!IsPopupCalendarOpen) OnValueChanged(e); else _FireValueChangedOnPopupClose = true; } protected override bool IsWatermarkRendered { get { return !(this.Focused || _FreeTextEntryBox != null && _FreeTextEntryBox.Focused) && _DateInputGroup.IsEmpty; } } private bool _ShowCheckBox = false; /// /// Gets or sets a value indicating whether a check box is displayed to the left of the selected date. /// Set to true if a check box is displayed to the left of the selected date; otherwise, false. The default is false. /// /// When the ShowCheckBox property is set to true, a check box is displayed to the left of the date in the control. When the check box is selected, the date/time value can be updated. When the check box is cleared, the date/time value is unable to be changed. /// You can handle the LockUpdateChanged event to be notified when this check box is checked and unchecked. Use LockUpdateChecked property /// to get or sets whether check box is checked. /// /// [DefaultValue(false), Description("Indicates whether a check box is displayed to the left of the input value which allows locking of the control.")] public bool ShowCheckBox { get { return _ShowCheckBox; } set { _ShowCheckBox = value; OnFormatChanged(); } } /// /// Gets or sets a value indicating whether a spin button control (up-down control) is used to adjust the date/time value. The default is false. /// /// When the ShowUpDown property is set to true, a spin button control is shown to adjust value of currently focused input item. /// The date and time can be adjusted by selecting each element individually and using the up and down buttons to change the value. /// /// private bool _ShowUpDown = false; [DefaultValue(false)] public bool ShowUpDown { get { return _ShowUpDown; } set { _ShowUpDown = value; OnFormatChanged(); } } /// /// Gets or sets the date time value of the control. You can use IsEmpty property to check whether control holds an empty value. /// Setting this property to System.DateTime(0) will also make the control Empty if AllowEmptyState=true. /// [Description("Indicates date time value of the control"), Bindable(BindableSupport.Yes)] public System.DateTime Value { get { return _DateInputGroup.Value; } set { if (this.AllowEmptyState && value.Equals(new System.DateTime(((long)(0))))) this.IsEmpty = true; else _DateInputGroup.Value = value; } } /// /// Gets whether Value property should be serialized by Windows Forms designer. /// /// true if value serialized otherwise false. [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeValue() { if (!this.AllowEmptyState && this.Value.Date == DateTime.Today) return false; return !_DateInputGroup.IsEmpty; } /// /// Resets Value property to default value. Used by Windows Forms designer. /// public void ResetValue() { if (this.AllowEmptyState) this.IsEmpty = true; else this.Value = DateTime.Now; } public override string Text { get { return base.Text; } set { this.ValueObject = value; } } /// /// Gets or sets the date/time value of the control as an object. This property allows you to bind to the database fields and supports /// null values. Expected value is DateTime object or null to indicate no date selected. /// [Bindable(true), RefreshProperties(RefreshProperties.All), TypeConverter(typeof(DateTimeConverter)), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object ValueObject { get { if (this.IsEmpty) return null; return Value; } set { if (AcceptCustomValueObject(value)) return; else if (IsNull(value) || value is string && value=="") this.IsEmpty = true; else if (value is System.DateTime) { this.Value = (System.DateTime)value; } else if (value is string) { System.DateTime d = new System.DateTime(); if (System.DateTime.TryParse(value.ToString(), out d)) this.Value = d; else throw new ArgumentException("ValueObject property expects either null/nothing value or DateTime type."); } else throw new ArgumentException("ValueObject property expects either null/nothing value or DateTime type."); } } private bool AcceptCustomValueObject(object value) { ParseDateTimeValueEventArgs e = new ParseDateTimeValueEventArgs(value); OnParseValue(e); if (e.IsParsed) { this.Value = e.ParsedValue; } return e.IsParsed; } /// /// Raises the ParseValue event. /// /// Provides event arguments. protected virtual void OnParseValue(ParseDateTimeValueEventArgs e) { if (ParseValue != null) ParseValue(this, e); } /// /// Gets or sets the values of the nested DateTimeGroup items. /// /// When nested date-time groups are used note that some of the features of the control are disabled, notably minimum and maximum values /// for nested date-times. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public System.DateTime[] Values { get { return _DateInputGroup.Values; } set { _DateInputGroup.Values = value; } } /// /// Gets or sets whether empty null/nothing state of the control is allowed. Default value is true which means that IsEmpty property /// may return true if input value is resets or ValueObject set to null/nothing. /// [DefaultValue(true), Description("Indicates whether empty null/nothing state of the control is allowed.")] public bool AllowEmptyState { get { return _DateInputGroup.AllowEmptyState; } set { _DateInputGroup.AllowEmptyState = value; this.Invalidate(); } } /// /// Gets or sets whether control is empty i.e. it does not hold a valid DateTime value. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsEmpty { get { return _DateInputGroup.IsEmpty; } set { _DateInputGroup.IsEmpty = value; } } /// /// Gets or sets the minimum date and time that can be selected in the control. /// [Description("Indicates minimum date and time that can be selected in the control.")] public System.DateTime MinDate { get { return _DateInputGroup.MinDate; } set { _DateInputGroup.MinDate = value; } } /// /// Gets whether Value property should be serialized by Windows Forms designer. /// /// true if value serialized otherwise false. public bool ShouldSerializeMinDate() { return !MinDate.Equals(DateTimeGroup.MinDateTime); } /// /// Reset the MinDate property to its default value. /// public void ResetMinDate() { MinDate = DateTimeGroup.MinDateTime; } /// /// Gets or sets the maximum date and time that can be selected in the control. /// [Description("Indicates maximum date and time that can be selected in the control.")] public System.DateTime MaxDate { get { return _DateInputGroup.MaxDate; } set { _DateInputGroup.MaxDate = value; } } /// /// Gets whether Value property should be serialized by Windows Forms designer. /// /// true if value serialized otherwise false. public bool ShouldSerializeMaxDate() { return !_DateInputGroup.MaxDate.Equals(DateTimeGroup.MaxDateTime); } /// /// Reset the MaxDate property to its default value. /// public void ResetMaxDate() { MaxDate = DateTimeGroup.MaxDateTime; } private eDateTimePickerFormat _Format = eDateTimePickerFormat.Short; /// /// Gets or sets the format date/time is displayed in. To specify custom format set this value to Custom and specify custom format using CustomFormat property. /// [DefaultValue(eDateTimePickerFormat.Short)] public eDateTimePickerFormat Format { get { return _Format; } set { if (_Format != value) { _Format = value; OnFormatChanged(); } } } private string _CustomFormat = ""; /// /// Gets or sets the custom date/time format string. /// /// /// /// To display string literals that contain date and time separators or format strings listed below, /// you must use escape characters in the substring. For example, to display the date as "June 15 at 12:00 PM", /// set the CustomFormat property to "MMMM dd 'at' t:mm tt". If the "at" substring is not enclosed by escape characters, /// the result is "June 15 aP 12:00PM" because the "t" character is read as the one-letter A.M./P.M. format string (see the format string table below). /// /// /// To display single quote in custom format use two single quotes characters like so '' after each other and they will be displayed as single quote. /// /// The following list shows all the valid format strings and their descriptions: /// /// /// Format String /// Description /// /// /// d /// The one- or two-digit day. /// /// /// dd /// The two-digit day. Single-digit day values are preceded by a 0. /// /// /// ddd /// The three-character day-of-week abbreviation. /// /// /// dddd /// The full day-of-week name. /// /// /// jjj /// The three-digit day-of-year day. Single and two-digit values are preceded by 0. /// /// /// j /// The three-digit day-of-year day. /// /// /// h /// The one- or two-digit hour in 12-hour format. /// /// /// hh /// The two-digit hour in 12-hour format. Single digit values are preceded by a 0. /// /// /// H /// The one- or two-digit hour in 24-hour format. /// /// /// HH /// The two-digit hour in 24-hour format. Single digit values are preceded by a 0. /// /// /// m /// The one- or two-digit minute. /// /// /// mm /// The two-digit minute. Single digit values are preceded by a 0. /// /// /// M /// The one- or two-digit month number. /// /// /// MM /// The two-digit month number. Single digit values are preceded by a 0. /// /// /// MMM /// The three-character month abbreviation. /// /// /// MMMM /// The full month name. /// /// /// s /// The one- or two-digit seconds. /// /// /// ss /// The two-digit seconds. Single digit values are preceded by a 0. /// /// /// t /// The one-letter A.M./P.M. abbreviation (A.M. is displayed as "A"). /// /// /// tt /// The two-letter A.M./P.M. abbreviation (A.M. is displayed as "AM"). /// /// /// y /// The one-digit year (2001 is displayed as "1"). /// /// /// yy /// The last two digits of the year (2001 is displayed as "01"). /// /// /// yyyy /// The full year (2001 is displayed as "2001"). /// /// /// { /// Starts the nested date-time group inside of the control. Note that nested groups must always be closed. /// Nested date-time groups can be used to represent range of input date/time values in the control /// To access nested values use Values property. For example to have control represent the input from two time values you could set /// CustomFormat to 'from' {HH:mm} 'to' {HH:mm} which will create two nested date/time groups that represent the time value. Entered /// time values can be accessed through Values property which return an array of all input values. /// /// /// } /// Ends the nested date-time input group. /// /// /// [DefaultValue(""), Description("Indicates the custom date/time format string. "), Localizable(true)] public string CustomFormat { get { return _CustomFormat; } set { if (value == null) value = ""; if (value != _CustomFormat) { _CustomFormat = value; OnFormatChanged(); } } } private void OnFormatChanged() { FormatToDateTimeGroup(); Invalidate(); UpdateSelectorVisibility(); if (FormatChanged != null) FormatChanged(this, new EventArgs()); } private void FormatToDateTimeGroup() { if (_CustomFormat.Length > 0 && _Format == eDateTimePickerFormat.Custom) ParseFormat(this.CustomFormat); else if (_Format != eDateTimePickerFormat.Custom) ParseFormat(GetSystemFormatString(_Format)); else _DateInputGroup.Items.Clear(); } private string GetSystemFormatString(eDateTimePickerFormat format) { if (format == eDateTimePickerFormat.Long) return DateTimeInput.GetActiveCulture().DateTimeFormat.LongDatePattern; else if (format == eDateTimePickerFormat.Short) return DateTimeInput.GetActiveCulture().DateTimeFormat.ShortDatePattern; else if (format == eDateTimePickerFormat.ShortTime) return DateTimeInput.GetActiveCulture().DateTimeFormat.ShortTimePattern; else if (format == eDateTimePickerFormat.LongTime) return DateTimeInput.GetActiveCulture().DateTimeFormat.LongTimePattern; return ""; } private static CultureInfo _CurrentCulture = null; /// /// Gets or sets the CultureInfo for the culture used by the DateTime Input controls and Month Calendar controls. /// Default value is null which indicates that controls will use CurrentUICulture. /// public static CultureInfo CurrentCulture { get { return _CurrentCulture; } set { _CurrentCulture = value; } } /// /// Gets the Culture used by the date time input and month calendar controls /// /// reference to CultureInfo public static CultureInfo GetActiveCulture() { return _CurrentCulture != null ? _CurrentCulture : CultureInfo.CurrentCulture; } /// /// Gets or sets whether auto-overwrite functionality for input is enabled. When in auto-overwrite mode input field will erase existing entry /// and start new one if typing is continued after InputComplete method is called. /// [DefaultValue(true), Description("Indicates whether auto-overwrite functionality for input is enabled.")] public bool AutoOverwrite { get { return _DateInputGroup.AutoOverwrite; } set { _DateInputGroup.AutoOverwrite = value; } } private void ParseFormat(string format) { _DateInputGroup.Items.Clear(); if (_ShowCheckBox) { LockUpdateCheckBox checkBox = new LockUpdateCheckBox(); _DateInputGroup.Items.Add(checkBox); checkBox.CheckedChanged += new EventHandler(LockCheckedChanged); } if (format.Length == 0) return; StringBuilder inputStack = new StringBuilder(format.Length); bool quote = false; Stack groupStack = new Stack(); VisualGroup currentGroup = _DateInputGroup; for (int i = 0; i < format.Length; i++) { if (format[i] == '\'') // Trigger/Exit quote mode { if (quote) quote = false; else quote = true; continue; } if (quote) // Quote mode adds everything under the quotes { inputStack.Append(format[i]); continue; } string s = format.Substring(i, Math.Min(4, format.Length - i)); bool match = false; if (s == "dddd") // The full day-of-week name or three-character day-of-week abbreviation. { DayLabelItem dayLabel = new DayLabelItem(); currentGroup.Items.Add(dayLabel); i += 3; match = true; } else if (s == "MMMM") // Full month name { MonthNameInput month = new MonthNameInput(); currentGroup.Items.Add(month); i += 3; match = true; } else if (s == "yyyy") // 4 digit year { NumericYearInput year = new NumericYearInput(); currentGroup.Items.Add(year); i += 3; match = true; } if (!match) { s = format.Substring(i, Math.Min(3, format.Length - i)); if (s == "ddd") // The three-character day-of-week abbreviation. { DayLabelItem dayLabel = new DayLabelItem(); dayLabel.UseAbbreviatedNames = true; currentGroup.Items.Add(dayLabel); i += 2; match = true; } else if (s == "MMM") // The three-character month abbreviation. { MonthNameInput month = new MonthNameInput(); month.UseAbbreviatedNames = true; currentGroup.Items.Add(month); i += 2; match = true; } else if (s == "jjj") // The three-digit day of year... { NumericDayOfYearInput day = new NumericDayOfYearInput(); day.DisplayFormat = "000"; currentGroup.Items.Add(day); i += 2; match = true; } } if (!match) { s = format.Substring(i, Math.Min(2, format.Length - i)); if (s == "dd") // The two-digit day. Single-digit day values are preceded by a 0. { NumericDayInput day = new NumericDayInput(); day.DisplayFormat = "00"; currentGroup.Items.Add(day); i += 1; match = true; } else if (s == "hh") // The two-digit hour in 12-hour format. Single digit values are preceded by a 0. { NumericHourInput hour = new NumericHourInput(); hour.DisplayFormat = "00"; hour.Is24HourFormat = false; currentGroup.Items.Add(hour); i += 1; match = true; } else if (s == "HH") // The two-digit hour in 24-hour format. Single digit values are preceded by a 0. { NumericHourInput hour = new NumericHourInput(); hour.DisplayFormat = "00"; hour.Is24HourFormat = true; currentGroup.Items.Add(hour); i += 1; match = true; } else if (s == "mm") // The two-digit minute. Single digit values are preceded by a 0. { NumericMinuteInput minute = new NumericMinuteInput(); minute.DisplayFormat = "00"; currentGroup.Items.Add(minute); i += 1; match = true; } else if (s == "MM") // The two-digit month number. Single digit values are preceded by a 0. { NumericMonthInput month = new NumericMonthInput(); month.DisplayFormat = "00"; currentGroup.Items.Add(month); i += 1; match = true; } else if (s == "ss") // The two-digit seconds. Single digit values are preceded by a 0. { NumericSecondInput second = new NumericSecondInput(); second.DisplayFormat = "00"; currentGroup.Items.Add(second); i += 1; match = true; } else if (s == "tt") // The two-letter A.M./P.M. abbreviation (A.M. is displayed as "AM"). { HourPeriodInput period = new HourPeriodInput(); currentGroup.Items.Add(period); i += 1; match = true; } else if (s == "yy") // The last two digits of the year (2001 is displayed as "01"). { NumericYearInput year = new NumericYearInput(); year.YearDisplayFormat = eYearDisplayFormat.TwoDigit; currentGroup.Items.Add(year); i += 1; match = true; } } if (!match) { s = format[i].ToString(); if (s == "d") // The one- or two-digit day. { NumericDayInput day = new NumericDayInput(); currentGroup.Items.Add(day); match = true; } else if (s == "h") // The one- or two-digit hour in 12-hour format. { NumericHourInput hour = new NumericHourInput(); hour.Is24HourFormat = false; currentGroup.Items.Add(hour); match = true; } else if (s == "H") //The one- or two-digit hour in 24-hour format. { NumericHourInput hour = new NumericHourInput(); hour.Is24HourFormat = true; currentGroup.Items.Add(hour); match = true; } else if (s == "m") // The one- or two-digit minute. { NumericMinuteInput minute = new NumericMinuteInput(); currentGroup.Items.Add(minute); match = true; } else if (s == "M") // The one- or two-digit month number. { NumericMonthInput month = new NumericMonthInput(); currentGroup.Items.Add(month); match = true; } else if (s == "s") // The one- or two-digit seconds. { NumericSecondInput second = new NumericSecondInput(); currentGroup.Items.Add(second); match = true; } else if (s == "t") // The one-letter A.M./P.M. abbreviation (A.M. is displayed as "A"). { HourPeriodInput period = new HourPeriodInput(); period.UseSingleLetterLabel = true; currentGroup.Items.Add(period); match = true; } else if (s == "y") // The one-digit year (2001 is displayed as "1"). { NumericYearInput year = new NumericYearInput(); year.YearDisplayFormat = eYearDisplayFormat.OneDigit; currentGroup.Items.Add(year); match = true; } else if (s == "j") // The three-digit day of year... { NumericDayOfYearInput day = new NumericDayOfYearInput(); currentGroup.Items.Add(day); match = true; } else if (s == "{") // Begins the group of data entries { if (inputStack.Length > 0) { VisualLabel label = new VisualLabel(); label.Text = inputStack.ToString(); currentGroup.Items.Add(label); inputStack = new StringBuilder(format.Length); } DateTimeGroup group = new DateTimeGroup(); currentGroup.Items.Add(group); groupStack.Push(currentGroup); currentGroup = group; match = true; } else if (s == "}") // Ends the group of data entries { currentGroup = groupStack.Pop(); match = true; } } if (match) { if (inputStack.Length > 0) { VisualLabel label = new VisualLabel(); label.Text = inputStack.ToString(); //label.TextPadding = new DevComponents.DotNetBar.Padding(0, 1, 0, 0); currentGroup.Items.Insert(currentGroup.Items.Count - 1, label); inputStack = new StringBuilder(format.Length); } } else inputStack.Append(format[i]); } if (inputStack.Length > 0) { VisualLabel label = new VisualLabel(); label.Text = inputStack.ToString(); currentGroup.Items.Add(label); } if (_ShowUpDown) { VisualUpDownButton upDownButton = new VisualUpDownButton(); upDownButton.Alignment = eItemAlignment.Right; upDownButton.AutoChange = eUpDownButtonAutoChange.FocusedItem; _DateInputGroup.Items.Add(upDownButton); } RecreateButtons(); if (_ShowCheckBox) this.LockUpdateCheckBox.Checked = _LockUpdateChecked; } private LockUpdateCheckBox LockUpdateCheckBox { get { if (_DateInputGroup.Items[0] is LockUpdateCheckBox) return (LockUpdateCheckBox)_DateInputGroup.Items[0]; return null; } } private void LockCheckedChanged(object sender, EventArgs e) { LockUpdateCheckBox checkBox = LockUpdateCheckBox; if (checkBox != null) _LockUpdateChecked = checkBox.Checked; OnLockUpdateChanged(e); } private bool _LockUpdateChecked = true; /// /// Gets or sets whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked. /// [DefaultValue(true), Description("Indicates whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.")] public bool LockUpdateChecked { get { return _LockUpdateChecked; } set { if (_LockUpdateChecked != value) { _LockUpdateChecked = value; LockUpdateCheckBox checkBox = LockUpdateCheckBox; if (checkBox != null) checkBox.Checked = _LockUpdateChecked; } } } /// /// Raises the LockUpdateChanged event. /// /// Provides event data./ protected virtual void OnLockUpdateChanged(EventArgs e) { if (LockUpdateChanged != null) LockUpdateChanged(this, e); } /// /// Raises the ValueChanged event. /// /// Provides event arguments. protected virtual void OnValueChanged(EventArgs e) { if (IsInitializing) return; if (ValueChanged != null) ValueChanged(this, e); if (ValueObjectChanged != null) ValueObjectChanged(this, e); if (this.IsEmpty) { base.Text = ""; } else { string format = ""; if (this.Format == eDateTimePickerFormat.Custom) format = this.CustomFormat; else format = GetSystemFormatString(this.Format); if (format == "") format = GetSystemFormatString(eDateTimePickerFormat.Short); if (format == "") base.Text = this.Value.ToString(); else { try { base.Text = this.Value.ToString(format); } catch { base.Text = ""; } } } if (FreeTextEntryMode && _FreeTextEntryBox != null) _FreeTextEntryBox.Text = this.Text; ExecuteCommand(); } protected override void OnValidating(CancelEventArgs e) { _DateInputGroup.UpdateValue(false); base.OnValidating(e); } private InputButtonSettings _ButtonDropDown = null; /// /// Gets the object that describes the settings for the button that shows drop-down calendar when clicked. /// [Category("Buttons"), Description("Describes the settings for the button that shows drop-down calendar when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public InputButtonSettings ButtonDropDown { get { return _ButtonDropDown; } } private InputButtonSettings _ButtonClear = null; /// /// Gets the object that describes the settings for the button that clears the content of the control when clicked. /// [Category("Buttons"), Description("Describes the settings for the button that clears the content of the control when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public InputButtonSettings ButtonClear { get { return _ButtonClear; } } protected override System.Collections.SortedList CreateSortedButtonList() { SortedList list = base.CreateSortedButtonList(); if (_ButtonClear.Visible) { VisualItem button = CreateButton(_ButtonClear); if (_ButtonClear.ItemReference != null) _ButtonClear.ItemReference.Click -= new EventHandler(ClearButtonClick); _ButtonClear.ItemReference = button; button.Click += new EventHandler(ClearButtonClick); list.Add(_ButtonClear, button); } if (_ButtonDropDown.Visible) { VisualItem button = CreateButton(_ButtonDropDown); if (_ButtonDropDown.ItemReference != null) { _ButtonDropDown.ItemReference.MouseDown -= new MouseEventHandler(DropDownButtonMouseDown); _ButtonDropDown.ItemReference.Click -= new EventHandler(DropDownButtonClick); } _ButtonDropDown.ItemReference = button; button.MouseDown += new MouseEventHandler(DropDownButtonMouseDown); button.Click += new EventHandler(DropDownButtonClick); list.Add(_ButtonDropDown, button); } if (_ButtonFreeText.Visible) { VisualItem button = CreateButton(_ButtonFreeText); if (_ButtonFreeText.ItemReference != null) _ButtonFreeText.ItemReference.Click -= new EventHandler(FreeTextButtonClick); _ButtonFreeText.ItemReference = button; button.Click += FreeTextButtonClick; list.Add(_ButtonFreeText, button); } return list; } private void DropDownButtonClick(object sender, EventArgs e) { if (e is KeyEventArgs) { ToggleCalendarPopup(); } } private void DropDownButtonMouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left || _CloseTime != DateTime.MinValue && DateTime.Now.Subtract(_CloseTime).TotalMilliseconds < 150) { _CloseTime = DateTime.MinValue; return; } ToggleCalendarPopup(); } private void ToggleCalendarPopup() { CancelEventArgs cancelArgs = new CancelEventArgs(); OnButtonDropDownClick(cancelArgs); if (cancelArgs.Cancel) return; _PopupItem.SetDisplayRectangle(this.ClientRectangle); _MonthCalendar.ReloadLocalizedStrings(); // Check the day size in case larger font is applied to the control if (this.Font.Height > Dpi.Height(_MonthCalendar.DaySize.Height)) { _MonthCalendar.DaySize = new Size((int)Math.Ceiling(this.Font.Height * 1.6f), this.Font.Height + 1); } if (this.RightToLeft == RightToLeft.No) _PopupItem.PopupLocation = new Point(this.Width - _PopupItem.PopupSize.Width, this.Height); if (this.MinDate != DateTime.MinValue) _MonthCalendar.MinDate = this.MinDate.Date; //.AddDays(-(this.MinDate.Day - 1)); else _MonthCalendar.MinDate = this.MinDate; _MonthCalendar.MaxDate = this.MaxDate.Date; if (!this.IsEmpty) { _MonthCalendar.SelectedDate = this.Value; _TimeSelector.SelectedDateTime = this.Value; } else { _MonthCalendar.SelectedDate = DateTime.MinValue; _TimeSelector.SelectedTime = TimeSpan.Zero; } if (_MonthCalendar.SelectedDate != DateTime.MinValue) _MonthCalendar.DisplayMonth = _MonthCalendar.SelectedDate; else _MonthCalendar.DisplayMonth = DateTime.Today; _PopupItem.Expanded = !_PopupItem.Expanded; } private bool _FireValueChangedOnPopupClose = false; private DateTime _CloseTime = DateTime.MinValue; private void DropDownPopupClose(object sender, EventArgs e) { if (_FireValueChangedOnPopupClose) OnValueChanged(EventArgs.Empty); _FireValueChangedOnPopupClose = false; _CloseTime = DateTime.Now; if (_MonthCalendar != null) _MonthCalendar.DropDownClosed(); if (_TimeSelector != null) _TimeSelector.DropDownClosed(); } //protected override bool ProcessCmdKey(ref Message msg, Keys keyData) //{ // if ((keyData & Keys.Down) == Keys.Down && Control.ModifierKeys == Keys.Alt) // { // if (_PopupItem != null && !_PopupItem.Expanded) // ToggleCalendarPopup(); // } // return base.ProcessCmdKey(ref msg, keyData); //} private void ClearButtonClick(object sender, EventArgs e) { CancelEventArgs cancelArgs = new CancelEventArgs(); OnButtonClearClick(cancelArgs); if (cancelArgs.Cancel) return; this.IsEmpty = true; } private InputButtonSettings _ButtonFreeText = null; /// /// Gets the object that describes the settings for the button that switches the control into the free-text entry mode when clicked. /// [Category("Buttons"), Description("Describes the settings for the button that switches the control into the free-text entry mode when clicked."), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public InputButtonSettings ButtonFreeText { get { return _ButtonFreeText; } } protected override VisualItem CreateButton(InputButtonSettings buttonSettings) { VisualItem item = null; if (buttonSettings == _ButtonDropDown) { item = new VisualDropDownButton(); ApplyButtonSettings(buttonSettings, item as VisualButton); } else item = base.CreateButton(buttonSettings); VisualButton button = item as VisualButton; button.ClickAutoRepeat = false; if (buttonSettings == _ButtonClear) { if (buttonSettings.Image == null && string.IsNullOrEmpty(buttonSettings.Text)) { //if (Dpi.Factor.Width > 1) button.Symbol = "\uf00d"; //else // button.Image = DevComponents.DotNetBar.BarFunctions.LoadBitmap("SystemImages.DateReset.png"); } } else if (buttonSettings == _ButtonFreeText) { if (buttonSettings.Image == null && string.IsNullOrEmpty(buttonSettings.Text)) { //if (Dpi.Factor.Width > 1) button.Symbol = "\uf040"; //else // button.Image = DevComponents.DotNetBar.BarFunctions.LoadBitmap("SystemImages.FreeText.png"); } button.Checked = buttonSettings.Checked; } return item; } /// /// Raises the ButtonClearClick event. /// /// protected virtual void OnButtonClearClick(CancelEventArgs e) { if (ButtonClearClick != null) ButtonClearClick(this, e); } /// /// Raises the ButtonDropDownClick event. /// /// protected virtual void OnButtonDropDownClick(CancelEventArgs e) { if (ButtonDropDownClick != null) ButtonDropDownClick(this, e); } /// /// Gets or sets whether input part of the control is read-only. When set to true the input part of the control becomes /// read-only and does not allow the typing. However, drop-down part if visible still allows user to change the value of the control /// Use this property to allow change of the value through drop-down picker only. /// [DefaultValue(false), Description("Indicates whether input part of the control is read-only.")] public bool IsInputReadOnly { get { return _DateInputGroup.IsReadOnly; } set { _DateInputGroup.IsReadOnly = value; if (_FreeTextEntryBox != null) _FreeTextEntryBox.ReadOnly = value; } } /// /// Gets or sets whether empty input values (year, month or day) are set to defaults while user is entering data. Default value is true. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether empty input values (year, month or day) are set to defaults while user is entering data")] public bool DefaultInputValues { get { return _DateInputGroup.DefaultInputValues; } set { _DateInputGroup.DefaultInputValues = value; } } /// /// Gets the reference to the internal MonthCalendarItem control which is used to display calendar when drop-down is open. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("Gets the reference to the internal MonthCalendarAdv control which is used to display calendar when drop-down is open.")] public MonthCalendarItem MonthCalendar { get { return _MonthCalendar; } } protected override Size DefaultSize { get { return new Size(200, base.DefaultSize.Height); } } private bool _AutoSelectDate = false; /// /// Gets or sets whether first day in month is automatically selected on popup date picker when month or year is changed. /// [Browsable(true), DefaultValue(false), Category("Behavior"), Description("Indicates whether first day in month is automatically selected on popup date picker when month or year is changed.")] public bool AutoSelectDate { get { return _AutoSelectDate; } set { _AutoSelectDate = value; } } private bool _AutoAdvance = false; /// /// Gets or sets whether input focus is automatically advanced to next input field when input is complete in current one. /// [DefaultValue(false), Category("Behavior"), Description("Indicates whether input focus is automatically advanced to next input field when input is complete in current one.")] public bool AutoAdvance { get { return _DateInputGroup.AutoAdvance; } set { if (_DateInputGroup.AutoAdvance != value) { _DateInputGroup.AutoAdvance = value; } } } /// /// List of characters that when pressed would select next input field. For example if you are /// allowing time input you could set this property to : so when user presses the : character, /// the input is forwarded to the next input field. /// [DefaultValue(""), Category("Behavior"), Description("List of characters that when pressed would select next input field.")] public string SelectNextInputCharacters { get { return _DateInputGroup.SelectNextInputCharacters; } set { if (_DateInputGroup.SelectNextInputCharacters != value) { _DateInputGroup.SelectNextInputCharacters = value; } } } private eDateTimeSelectorVisibility _DateTimeSelectorVisibility = eDateTimeSelectorVisibility.Auto; /// /// Gets or sets the date-time selectors visibility on popup. Default value is Auto which will select selector visibility based on Format property setting. /// [DefaultValue(eDateTimeSelectorVisibility.Auto), Category("Behavior"), Description("")] public eDateTimeSelectorVisibility DateTimeSelectorVisibility { get { return _DateTimeSelectorVisibility; } set { if (value != _DateTimeSelectorVisibility) { eDateTimeSelectorVisibility oldValue = _DateTimeSelectorVisibility; _DateTimeSelectorVisibility = value; OnDateTimeSelectorVisibilityChanged(oldValue, value); } } } private void UpdateSelectorVisibility() { bool timeSelectorVisible = false; bool dateSelectorVisible = true; if (_DateTimeSelectorVisibility == eDateTimeSelectorVisibility.Auto) { if (_Format == eDateTimePickerFormat.LongTime || _Format == eDateTimePickerFormat.ShortTime) { timeSelectorVisible = true; dateSelectorVisible = false; } } else if (_DateTimeSelectorVisibility == eDateTimeSelectorVisibility.TimeSelector) { timeSelectorVisible = true; dateSelectorVisible = false; } else if (_DateTimeSelectorVisibility == eDateTimeSelectorVisibility.Both) timeSelectorVisible = true; _MonthCalendar.Visible = dateSelectorVisible; _TimeSelector.Visible = timeSelectorVisible; if (dateSelectorVisible && timeSelectorVisible) { _Spacer.Visible = true; //_MonthCalendar.DaySize = new Size(28, 19); _MonthCalendar.DayClickAutoClosePopup = false; } else { _Spacer.Visible = false; //_MonthCalendar.ResetDaySize(); _MonthCalendar.DayClickAutoClosePopup = true; } } /// /// Returns reference to internal time selector item which is used on drop-down to select time when control is used in time entry mode. /// [Browsable(false)] public TimeSelectorItem TimeSelectorItem { get { return _TimeSelector; } } /// /// Called when DateTimeSelectorVisibility property has changed. /// /// Old property value /// New property value protected virtual void OnDateTimeSelectorVisibilityChanged(eDateTimeSelectorVisibility oldValue, eDateTimeSelectorVisibility newValue) { //OnPropertyChanged(new PropertyChangedEventArgs("DateTimeSelectorVisibility")); UpdateSelectorVisibility(); } private eTimeSelectorFormat _TimeSelectorTimeFormat = eTimeSelectorFormat.System; /// /// Gets or sets the popup time selector time format used to present time by the selector i.e. 12H or 24H format. /// [DefaultValue(eTimeSelectorFormat.System), Category("Appearance"), Description("Indicates popup time selector time format used to present time by the selector i.e. 12H or 24H format."), Localizable(true)] public eTimeSelectorFormat TimeSelectorTimeFormat { get { return _TimeSelectorTimeFormat; } set { if (value != _TimeSelectorTimeFormat) { eTimeSelectorFormat oldValue = _TimeSelectorTimeFormat; _TimeSelectorTimeFormat = value; OnTimeSelectorTimeFormatChanged(oldValue, value); } } } /// /// Called when TimeFormat property has changed. /// /// Old property value /// New property value protected virtual void OnTimeSelectorTimeFormatChanged(eTimeSelectorFormat oldValue, eTimeSelectorFormat newValue) { if (_TimeSelector != null) _TimeSelector.TimeFormat = _TimeSelectorTimeFormat; } private eTimeSelectorType _TimeSelectorType = eTimeSelectorType.MonthCalendarStyle; /// /// Indicates the type of popup time selector used. /// [DefaultValue(eTimeSelectorType.MonthCalendarStyle), Category("Appearance"), Description("Indicates the type of popup time selector used.")] public eTimeSelectorType TimeSelectorType { get { return _TimeSelectorType; } set { if (value != _TimeSelectorType) { eTimeSelectorType oldValue = _TimeSelectorType; _TimeSelectorType = value; OnTimeSelectorTypeChanged(oldValue, value); } } } /// /// Called when TimeSelectorType property has changed. /// /// Old property value /// New property value protected virtual void OnTimeSelectorTypeChanged(eTimeSelectorType oldValue, eTimeSelectorType newValue) { //OnPropertyChanged(new PropertyChangedEventArgs("TimeSelectorType")); if (_TimeSelector != null) _TimeSelector.SelectorType = _TimeSelectorType; } #endregion #region ICommandSource Members protected virtual void ExecuteCommand() { if (_Command == null) return; CommandManager.ExecuteCommand(this); } /// /// Gets or sets the command assigned to the item. Default value is null. /// Note that if this property is set to null Enabled property will be set to false automatically to disable the item. /// [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")] public Command Command { get { return (Command)((ICommandSource)this).Command; } set { ((ICommandSource)this).Command = value; } } private ICommand _Command = null; [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] ICommand ICommandSource.Command { get { return _Command; } set { bool changed = false; if (_Command != value) changed = true; if (_Command != null) CommandManager.UnRegisterCommandSource(this, _Command); _Command = value; if (value != null) CommandManager.RegisterCommand(this, value); if (changed) OnCommandChanged(); } } /// /// Called when Command property value changes. /// protected virtual void OnCommandChanged() { } private object _CommandParameter = null; /// /// Gets or sets user defined data value that can be passed to the command when it is executed. /// [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)] public object CommandParameter { get { return _CommandParameter; } set { _CommandParameter = value; } } #endregion #region Free-Text Entry Support /// /// Occurs if Free-Text entry value is not natively recognized by the control and provides you with opportunity to convert that value to the /// value control expects. /// [Description("Occurs if Free-Text entry value is not natively recognized by the control and provides you with opportunity to convert that value to the value control expects."), Category("Free-Text")] public event FreeTextEntryConversionEventHandler ConvertFreeTextEntry; /// /// Occurs when Free-Text button is clicked and allows you to cancel its default action. /// public event CancelEventHandler ButtonFreeTextClick; private void FreeTextButtonClick(object sender, EventArgs e) { CancelEventArgs cancelArgs = new CancelEventArgs(); OnButtonFreeTextClick(cancelArgs); if (cancelArgs.Cancel) return; FreeTextEntryMode = !FreeTextEntryMode; _ButtonFreeText.Checked = FreeTextEntryMode; if (FreeTextEntryMode && _FreeTextEntryBox != null && !_FreeTextEntryBox.Focused) _FreeTextEntryBox.Focus(); } /// /// /// /// protected virtual void OnButtonFreeTextClick(CancelEventArgs e) { CancelEventHandler handler = ButtonFreeTextClick; if (handler != null) handler(this, e); } private bool _AutoResolveFreeTextEntries = true; /// /// Gets or sets whether free text entries are attempted to be auto-resolved to dates like Today to today's date or Now to date and time now etc. Default value is true. /// [DefaultValue(true), Category("Free-Text"), Description("Indicates whether free text entries are attempted to be auto-resolved to dates like Today to today's date or Now to date and time now etc.")] public bool AutoResolveFreeTextEntries { get { return _AutoResolveFreeTextEntries; } set { _AutoResolveFreeTextEntries = value; } } private bool _AutoOffFreeTextEntry = false; /// /// Gets or sets whether free-text entry is automatically turned off when control loses input focus. Default value is false. /// [DefaultValue(false), Category("Free-Text"), Description("Indicates whether free-text entry is automatically turned off when control loses input focus.")] public bool AutoOffFreeTextEntry { get { return _AutoOffFreeTextEntry; } set { _AutoOffFreeTextEntry = value; } } private bool _FreeTextEntryMode = false; /// /// Gets or sets whether control input is in free-text input mode. Default value is false. /// [DefaultValue(false), Category("Free-Text"), Description("Indicates whether control input is in free-text input mode.")] public bool FreeTextEntryMode { get { return _FreeTextEntryMode; } set { _FreeTextEntryMode = value; OnFreeTextEntryModeChanged(); } } private void OnFreeTextEntryModeChanged() { if (!_FreeTextEntryMode) { if (_FreeTextEntryBox != null) { _FreeTextEntryBox.ApplyValue -= ApplyFreeTextValue; _FreeTextEntryBox.RevertValue -= RevertFreeTextValue; _FreeTextEntryBox.LostFocus -= FreeTextLostFocus; this.Controls.Remove(_FreeTextEntryBox); _FreeTextEntryBox.Dispose(); _FreeTextEntryBox = null; } } else { UpdateFreeTextBoxVisibility(); } if (_ButtonFreeText != null) _ButtonFreeText.Checked = _FreeTextEntryMode; } protected override void OnIsKeyboardFocusWithinChanged() { if (_FreeTextEntryMode) { UpdateFreeTextBoxVisibility(); if (this.IsKeyboardFocusWithin) { Control textBox = GetFreeTextBox(); if (!textBox.Focused) textBox.Focus(); if (FocusHighlightEnabled) textBox.BackColor = this.FocusHighlightColor; } else if (FocusHighlightEnabled) { Control textBox = GetFreeTextBox(); textBox.BackColor = SystemColors.Window; } } base.OnIsKeyboardFocusWithinChanged(); } private void UpdateFreeTextBoxVisibility() { FreeTextEntryBox textBox = (FreeTextEntryBox)GetFreeTextBox(); if (this.IsKeyboardFocusWithin) { textBox.Visible = true; textBox.Text = this.Text; RootVisualItem.InvalidateArrange(); this.Invalidate(); } else { if (textBox.Visible) { if (textBox.Focused) textBox.HideOnLostFocus(); else textBox.Visible = false; RootVisualItem.InvalidateArrange(); this.Invalidate(); } } } protected override bool SupportsFreeTextEntry { get { return true; } } private FreeTextEntryBox _FreeTextEntryBox = null; protected override Control GetFreeTextBox() { if (_FreeTextEntryBox == null) { _FreeTextEntryBox = new FreeTextEntryBox(); _FreeTextEntryBox.ApplyValue += ApplyFreeTextValue; _FreeTextEntryBox.RevertValue += RevertFreeTextValue; _FreeTextEntryBox.LostFocus += FreeTextLostFocus; _FreeTextEntryBox.BorderStyle = BorderStyle.None; _FreeTextEntryBox.ReadOnly = this.IsInputReadOnly; this.Controls.Add(_FreeTextEntryBox); } return _FreeTextEntryBox; } private void RevertFreeTextValue(object sender, EventArgs e) { if (_FreeTextEntryBox != null) _FreeTextEntryBox.Text = this.Text; } protected virtual void OnConvertFreeTextEntry(FreeTextEntryConversionEventArgs e) { FreeTextEntryConversionEventHandler handler = this.ConvertFreeTextEntry; if (handler != null) handler(this, e); } private bool ParseFreeTextValue(out DateTime date) { try { return (this.Format == eDateTimePickerFormat.Custom && DateTime.TryParseExact(_FreeTextEntryBox.Text, this.CustomFormat, null, DateTimeStyles.None, out date) || DateTime.TryParse(_FreeTextEntryBox.Text, out date)) && _AutoResolveFreeTextEntries; } catch { date = DateTime.MinValue; return false; } } private void ApplyFreeTextValue(object sender, EventArgs e) { if (_FreeTextEntryBox == null) return; if (string.IsNullOrEmpty(_FreeTextEntryBox.Text)) this.ValueObject = null; else { DateTime date; if (ParseFreeTextValue(out date)) { this.Value = date; } else { FreeTextEntryConversionEventArgs eventArgs = new FreeTextEntryConversionEventArgs(_FreeTextEntryBox.Text); OnConvertFreeTextEntry(eventArgs); if (eventArgs.IsValueConverted) { if (eventArgs.ControlValue is DateTime) this.Value = (DateTime)eventArgs.ControlValue; else if (eventArgs.ControlValue == null) this.ValueObject = null; else throw new ArgumentException("ControlValue assigned is not DateTime type."); } else { if (_AutoResolveFreeTextEntries) { date=DateTime.MinValue; string text = _FreeTextEntryBox.Text.ToLower(); if (text == "now") date = DateTime.Now; else if (text == "today") date = DateTime.Today; else if (text == "tomorrow") date = DateTime.Today.AddDays(1); else if (text == "yesterday") date = DateTime.Today.AddDays(-1); if (date == DateTime.MinValue) this.ValueObject = null; else this.Value = date; } } } } } private void FreeTextLostFocus(object sender, EventArgs e) { if (_AutoOffFreeTextEntry && !this.IsKeyboardFocusWithin) this.FreeTextEntryMode = false; } protected override void HideFreeTextBoxEntry() { if (_FreeTextEntryBox != null) _FreeTextEntryBox.Visible = false; } protected override bool IsFreeTextEntryVisible { get { return _FreeTextEntryMode && this.IsKeyboardFocusWithin; } } #endregion } /// /// Defines the date-time selector visibility for DateTimeInput control popup. /// public enum eDateTimeSelectorVisibility { /// /// Depending on DateTimeInput.Format property setting either date or time selector is used. /// Auto, /// /// Only date selector is visible. /// DateSelector, /// /// Only time selector is visible on popup. /// TimeSelector, /// /// Both date and time selectors are visible. /// Both } } #endif