1943 lines
77 KiB
C#

#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
/// <summary>
/// Occurs when the Value or IsEmpty property changes.
/// <remarks>
/// This event is not raised when the entered date is earlier than MinDateTime or later than MaxDateTime.
/// </remarks>
/// </summary>
public event EventHandler ValueChanged;
/// <summary>
/// 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.
/// </summary>
public event EventHandler ValueObjectChanged;
/// <summary>
/// Occurs when the Format property value has changed.
/// </summary>
public event EventHandler FormatChanged;
/// <summary>
/// Occurs when Clear button is clicked and allows you to cancel the default action performed by the button.
/// </summary>
public event CancelEventHandler ButtonClearClick;
/// <summary>
/// Occurs when Drop-Down button that shows calendar is clicked and allows you to cancel showing of the popup.
/// </summary>
public event CancelEventHandler ButtonDropDownClick;
/// <summary>
/// Occurs when ValueObject property is set and it allows you to provide custom parsing for the values.
/// </summary>
public event ParseDateTimeValueEventHandler ParseValue;
/// <summary>
/// Occurs when ShowCheckBox property is set to true and user changes the lock status of the control by clicking the check-box.
/// </summary>
public event EventHandler LockUpdateChanged;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the DateTimeInput class.
/// </summary>
public DateTimeInput()
{
}
#endregion
#region Internal Implementation
/// <summary>
/// Copies the current value in the control to the Clipboard.
/// </summary>
public virtual void Copy()
{
if (_DateInputGroup != null) Clipboard.SetText(this.Text);
}
/// <summary>
/// Pastes the current Clipboard content if possible as the value into the control.
/// </summary>
public virtual void Paste()
{
if (_DateInputGroup != null) Text = Clipboard.GetText();
}
/// <summary>
/// Moves the current control value to the Clipboard.
/// </summary>
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);
}
/// <summary>
/// Gets whether popup calendar is open.
/// </summary>
[Browsable(false)]
public bool IsPopupCalendarOpen
{
get
{
return _PopupItem.Expanded;
}
set
{
if (_PopupItem.Expanded != value)
ToggleCalendarPopup();
}
}
private bool _PopupCalendarKeyboardNavigationEnabled = true;
/// <summary>
/// Gets or sets whether selected date on popup calendar can be changed using keyboard arrow keys.
/// </summary>
[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);
}
/// <summary>
/// Gets or sets the default date-time values that are used by the control.
/// </summary>
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;
/// <summary>
/// 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.
/// <remarks>
/// 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.
/// </remarks>
/// </summary>
[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();
}
}
/// <summary>
/// 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.
/// <remarks>
/// 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.
/// </remarks>
/// </summary>
private bool _ShowUpDown = false;
[DefaultValue(false)]
public bool ShowUpDown
{
get { return _ShowUpDown; }
set
{
_ShowUpDown = value;
OnFormatChanged();
}
}
/// <summary>
/// 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.
/// </summary>
[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;
}
}
/// <summary>
/// Gets whether Value property should be serialized by Windows Forms designer.
/// </summary>
/// <returns>true if value serialized otherwise false.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeValue()
{
if (!this.AllowEmptyState && this.Value.Date == DateTime.Today) return false;
return !_DateInputGroup.IsEmpty;
}
/// <summary>
/// Resets Value property to default value. Used by Windows Forms designer.
/// </summary>
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;
}
}
/// <summary>
/// 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.
/// </summary>
[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;
}
/// <summary>
/// Raises the ParseValue event.
/// </summary>
/// <param name="e">Provides event arguments.</param>
protected virtual void OnParseValue(ParseDateTimeValueEventArgs e)
{
if (ParseValue != null)
ParseValue(this, e);
}
/// <summary>
/// Gets or sets the values of the nested DateTimeGroup items.
/// <remarks>
/// 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.
/// </remarks>
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public System.DateTime[] Values
{
get { return _DateInputGroup.Values; }
set
{
_DateInputGroup.Values = value;
}
}
/// <summary>
/// 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.
/// </summary>
[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(); }
}
/// <summary>
/// Gets or sets whether control is empty i.e. it does not hold a valid DateTime value.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsEmpty
{
get { return _DateInputGroup.IsEmpty; }
set { _DateInputGroup.IsEmpty = value; }
}
/// <summary>
/// Gets or sets the minimum date and time that can be selected in the control.
/// </summary>
[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;
}
}
/// <summary>
/// Gets whether Value property should be serialized by Windows Forms designer.
/// </summary>
/// <returns>true if value serialized otherwise false.</returns>
public bool ShouldSerializeMinDate()
{
return !MinDate.Equals(DateTimeGroup.MinDateTime);
}
/// <summary>
/// Reset the MinDate property to its default value.
/// </summary>
public void ResetMinDate()
{
MinDate = DateTimeGroup.MinDateTime;
}
/// <summary>
/// Gets or sets the maximum date and time that can be selected in the control.
/// </summary>
[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; }
}
/// <summary>
/// Gets whether Value property should be serialized by Windows Forms designer.
/// </summary>
/// <returns>true if value serialized otherwise false.</returns>
public bool ShouldSerializeMaxDate()
{
return !_DateInputGroup.MaxDate.Equals(DateTimeGroup.MaxDateTime);
}
/// <summary>
/// Reset the MaxDate property to its default value.
/// </summary>
public void ResetMaxDate()
{
MaxDate = DateTimeGroup.MaxDateTime;
}
private eDateTimePickerFormat _Format = eDateTimePickerFormat.Short;
/// <summary>
/// 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.
/// </summary>
[DefaultValue(eDateTimePickerFormat.Short)]
public eDateTimePickerFormat Format
{
get { return _Format; }
set
{
if (_Format != value)
{
_Format = value;
OnFormatChanged();
}
}
}
private string _CustomFormat = "";
/// <summary>
/// Gets or sets the custom date/time format string.
/// </summary>
/// <remarks>
/// <para>
/// 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).
/// </para>
/// <para>
/// 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.
/// </para>
/// The following list shows all the valid format strings and their descriptions:
/// <list type="table">
/// <listheader>
/// <term>Format String</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>d</term>
/// <description>The one- or two-digit day.</description>
/// </item>
/// <item>
/// <term>dd</term>
/// <description>The two-digit day. Single-digit day values are preceded by a 0. </description>
/// </item>
/// <item>
/// <term>ddd</term>
/// <description>The three-character day-of-week abbreviation.</description>
/// </item>
/// <item>
/// <term>dddd</term>
/// <description>The full day-of-week name.</description>
/// </item>
/// <item>
/// <term>jjj</term>
/// <description>The three-digit day-of-year day. Single and two-digit values are preceded by 0.</description>
/// </item>
/// <item>
/// <term>j</term>
/// <description>The three-digit day-of-year day.</description>
/// </item>
/// <item>
/// <term>h</term>
/// <description>The one- or two-digit hour in 12-hour format.</description>
/// </item>
/// <item>
/// <term>hh</term>
/// <description>The two-digit hour in 12-hour format. Single digit values are preceded by a 0. </description>
/// </item>
/// <item>
/// <term>H</term>
/// <description>The one- or two-digit hour in 24-hour format. </description>
/// </item>
/// <item>
/// <term>HH</term>
/// <description>The two-digit hour in 24-hour format. Single digit values are preceded by a 0.</description>
/// </item>
/// <item>
/// <term>m</term>
/// <description>The one- or two-digit minute.</description>
/// </item>
/// <item>
/// <term>mm</term>
/// <description>The two-digit minute. Single digit values are preceded by a 0.</description>
/// </item>
/// <item>
/// <term>M</term>
/// <description>The one- or two-digit month number.</description>
/// </item>
/// <item>
/// <term>MM</term>
/// <description>The two-digit month number. Single digit values are preceded by a 0.</description>
/// </item>
/// <item>
/// <term>MMM</term>
/// <description>The three-character month abbreviation.</description>
/// </item>
/// <item>
/// <term>MMMM</term>
/// <description>The full month name.</description>
/// </item>
/// <item>
/// <term>s</term>
/// <description>The one- or two-digit seconds.</description>
/// </item>
/// <item>
/// <term>ss</term>
/// <description>The two-digit seconds. Single digit values are preceded by a 0.</description>
/// </item>
/// <item>
/// <term>t</term>
/// <description>The one-letter A.M./P.M. abbreviation (A.M. is displayed as "A").</description>
/// </item>
/// <item>
/// <term>tt</term>
/// <description>The two-letter A.M./P.M. abbreviation (A.M. is displayed as "AM").</description>
/// </item>
/// <item>
/// <term>y</term>
/// <description>The one-digit year (2001 is displayed as "1").</description>
/// </item>
/// <item>
/// <term>yy</term>
/// <description>The last two digits of the year (2001 is displayed as "01").</description>
/// </item>
/// <item>
/// <term>yyyy</term>
/// <description>The full year (2001 is displayed as "2001").</description>
/// </item>
/// <item>
/// <term>{</term>
/// <description>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.</description>
/// </item>
/// <item>
/// <term>}</term>
/// <description>Ends the nested date-time input group.</description>
/// </item>
/// </list>
/// </remarks>
[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;
/// <summary>
/// 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.
/// </summary>
public static CultureInfo CurrentCulture
{
get
{
return _CurrentCulture;
}
set
{
_CurrentCulture = value;
}
}
/// <summary>
/// Gets the Culture used by the date time input and month calendar controls
/// </summary>
/// <returns>reference to CultureInfo</returns>
public static CultureInfo GetActiveCulture()
{
return _CurrentCulture != null ? _CurrentCulture : CultureInfo.CurrentCulture;
}
/// <summary>
/// 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.
/// </summary>
[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<VisualGroup> groupStack = new Stack<VisualGroup>();
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;
/// <summary>
/// Gets or sets whether check box shown using ShowCheckBox property which locks/unlocks the control update is checked.
/// </summary>
[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;
}
}
}
/// <summary>
/// Raises the LockUpdateChanged event.
/// </summary>
/// <param name="e">Provides event data./</param>
protected virtual void OnLockUpdateChanged(EventArgs e)
{
if (LockUpdateChanged != null)
LockUpdateChanged(this, e);
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="e">Provides event arguments.</param>
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;
/// <summary>
/// Gets the object that describes the settings for the button that shows drop-down calendar when clicked.
/// </summary>
[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;
/// <summary>
/// Gets the object that describes the settings for the button that clears the content of the control when clicked.
/// </summary>
[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;
/// <summary>
/// Gets the object that describes the settings for the button that switches the control into the free-text entry mode when clicked.
/// </summary>
[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;
}
/// <summary>
/// Raises the ButtonClearClick event.
/// </summary>
/// <param name="e"></param>
protected virtual void OnButtonClearClick(CancelEventArgs e)
{
if (ButtonClearClick != null)
ButtonClearClick(this, e);
}
/// <summary>
/// Raises the ButtonDropDownClick event.
/// </summary>
/// <param name="e"></param>
protected virtual void OnButtonDropDownClick(CancelEventArgs e)
{
if (ButtonDropDownClick != null)
ButtonDropDownClick(this, e);
}
/// <summary>
/// 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.
/// </summary>
[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;
}
}
/// <summary>
/// Gets or sets whether empty input values (year, month or day) are set to defaults while user is entering data. Default value is true.
/// </summary>
[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;
}
}
/// <summary>
/// Gets the reference to the internal MonthCalendarItem control which is used to display calendar when drop-down is open.
/// </summary>
[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;
/// <summary>
/// Gets or sets whether first day in month is automatically selected on popup date picker when month or year is changed.
/// </summary>
[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;
/// <summary>
/// Gets or sets whether input focus is automatically advanced to next input field when input is complete in current one.
/// </summary>
[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;
}
}
}
/// <summary>
/// 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.
/// </summary>
[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;
/// <summary>
/// Gets or sets the date-time selectors visibility on popup. Default value is Auto which will select selector visibility based on Format property setting.
/// </summary>
[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;
}
}
/// <summary>
/// Returns reference to internal time selector item which is used on drop-down to select time when control is used in time entry mode.
/// </summary>
[Browsable(false)]
public TimeSelectorItem TimeSelectorItem
{
get { return _TimeSelector; }
}
/// <summary>
/// Called when DateTimeSelectorVisibility property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnDateTimeSelectorVisibilityChanged(eDateTimeSelectorVisibility oldValue, eDateTimeSelectorVisibility newValue)
{
//OnPropertyChanged(new PropertyChangedEventArgs("DateTimeSelectorVisibility"));
UpdateSelectorVisibility();
}
private eTimeSelectorFormat _TimeSelectorTimeFormat = eTimeSelectorFormat.System;
/// <summary>
/// Gets or sets the popup time selector time format used to present time by the selector i.e. 12H or 24H format.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TimeFormat property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
protected virtual void OnTimeSelectorTimeFormatChanged(eTimeSelectorFormat oldValue, eTimeSelectorFormat newValue)
{
if (_TimeSelector != null)
_TimeSelector.TimeFormat = _TimeSelectorTimeFormat;
}
private eTimeSelectorType _TimeSelectorType = eTimeSelectorType.MonthCalendarStyle;
/// <summary>
/// Indicates the type of popup time selector used.
/// </summary>
[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);
}
}
}
/// <summary>
/// Called when TimeSelectorType property has changed.
/// </summary>
/// <param name="oldValue">Old property value</param>
/// <param name="newValue">New property value</param>
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);
}
/// <summary>
/// Gets or sets the command assigned to the item. Default value is null.
/// <remarks>Note that if this property is set to null Enabled property will be set to false automatically to disable the item.</remarks>
/// </summary>
[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();
}
}
/// <summary>
/// Called when Command property value changes.
/// </summary>
protected virtual void OnCommandChanged()
{
}
private object _CommandParameter = null;
/// <summary>
/// Gets or sets user defined data value that can be passed to the command when it is executed.
/// </summary>
[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
/// <summary>
/// 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.
/// </summary>
[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;
/// <summary>
/// Occurs when Free-Text button is clicked and allows you to cancel its default action.
/// </summary>
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();
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected virtual void OnButtonFreeTextClick(CancelEventArgs e)
{
CancelEventHandler handler = ButtonFreeTextClick;
if (handler != null) handler(this, e);
}
private bool _AutoResolveFreeTextEntries = true;
/// <summary>
/// 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.
/// </summary>
[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;
/// <summary>
/// Gets or sets whether free-text entry is automatically turned off when control loses input focus. Default value is false.
/// </summary>
[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;
/// <summary>
/// Gets or sets whether control input is in free-text input mode. Default value is false.
/// </summary>
[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
}
/// <summary>
/// Defines the date-time selector visibility for DateTimeInput control popup.
/// </summary>
public enum eDateTimeSelectorVisibility
{
/// <summary>
/// Depending on DateTimeInput.Format property setting either date or time selector is used.
/// </summary>
Auto,
/// <summary>
/// Only date selector is visible.
/// </summary>
DateSelector,
/// <summary>
/// Only time selector is visible on popup.
/// </summary>
TimeSelector,
/// <summary>
/// Both date and time selectors are visible.
/// </summary>
Both
}
}
#endif