using System; using System.ComponentModel; using System.Windows.Forms; namespace Microsoft.Win32.TaskScheduler { #region Enumerations /// /// Determines the format of the control. /// public enum FullDateTimePickerTimeFormat { /// Shows hours, minutes and seconds LongTime, /// Shows hours and minutes ShortTime, /// No time box shown Hidden } #endregion Enumerations /// /// A single control that can represent a full date and time. /// [DefaultEvent("ValueChanged"), DefaultProperty("Value"), DefaultBindingProperty("Value")] [System.Drawing.ToolboxBitmap(typeof(Microsoft.Win32.TaskScheduler.TaskEditDialog), "Control")] public partial class FullDateTimePicker : UserControl { private DateTime currentValue; private bool initializing = false; private FullDateTimePickerTimeFormat timeFormat = FullDateTimePickerTimeFormat.LongTime; private bool userHasSetValue; private FieldConversionUtcCheckBehavior utcBehavior = FieldConversionUtcCheckBehavior.ConvertLocalToUtc; private string utcPrompt = "Synchronize across time zones"; /// /// Initializes a new instance of the class. /// public FullDateTimePicker() { InitializeComponent(); dateTimePickerTime.Format = DateTimePickerFormat.Custom; dateTimePickerTime.CustomFormat = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.LongTimePattern; ResetValue(); } /// /// Behavior of producing value when Utc check is checked /// public enum FieldConversionUtcCheckBehavior { /// Takes time in fields as local and produces value in Utc. ConvertLocalToUtc = 0, /// Takes time in fields as Utc and produces value in local. AssumeUtc = 1, /// Takes time in fields as local and leaves them local. AssumeLocal = 2 } /// /// Occurs when the property changes. /// [Category("Action"), Description("Occurs when the Value property changes.")] public event EventHandler ValueChanged; /// /// Gets or sets a value indicating whether [auto size]. /// /// true if [auto size]; otherwise, false. [Browsable(true), Category("Layout"), DefaultValue(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override bool AutoSize { get { return base.AutoSize; } set { base.AutoSize = value; } } /// /// Gets or sets how the control will resize itself. /// /// /// /// A value from the enumeration. The default is . /// [Browsable(true), Category("Layout"), Description("How the control will resize itself"), DefaultValue(AutoSizeMode.GrowAndShrink), Localizable(true)] public new AutoSizeMode AutoSizeMode { get { return base.AutoSizeMode; } set { base.AutoSizeMode = value; } } /// /// Gets or sets the text associated with this control. /// /// /// A string that represents the text associated with this control. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)] public override string Text { get { return base.Text; } set { if ((value == null) || (value.Length == 0)) this.ResetValue(); else this.Value = DateTime.Parse(value, System.Globalization.CultureInfo.CurrentCulture); } } /// /// Gets or sets the format of the time portion of the control. /// /// The time format. [RefreshProperties(RefreshProperties.Repaint), DefaultValue(FullDateTimePickerTimeFormat.LongTime), Category("Behavior")] [Description("The format of the time portion of the control.")] public FullDateTimePickerTimeFormat TimeFormat { get { return timeFormat; } set { if (timeFormat != value) { timeFormat = value; switch (value) { case FullDateTimePickerTimeFormat.ShortTime: dateTimePickerTime.Format = DateTimePickerFormat.Custom; dateTimePickerTime.CustomFormat = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortTimePattern; dateTimePickerTime.Visible = true; break; case FullDateTimePickerTimeFormat.Hidden: //dateTimePickerTime.Value = dateTimePickerTime.Value.Date; dateTimePickerTime.Visible = false; break; case FullDateTimePickerTimeFormat.LongTime: default: dateTimePickerTime.Format = DateTimePickerFormat.Custom; dateTimePickerTime.CustomFormat = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.LongTimePattern; dateTimePickerTime.Visible = true; break; } } } } /// /// Gets or sets how fields are processed when the Utc Checkbox is checked. /// /// The UTC check behavior. [DefaultValue(FieldConversionUtcCheckBehavior.ConvertLocalToUtc), Category("Behavior"), Description("Determines how to process fields when Utc Checkbox is checked")] public FieldConversionUtcCheckBehavior UtcCheckBehavior { get { return utcBehavior; } set { utcBehavior = value; } } /// /// Gets or sets the text prompt for the UTC CheckBox. Leave blank to remove the CheckBox. /// /// The text prompt for the UTC CheckBox. [RefreshProperties(RefreshProperties.Repaint), DefaultValue("Synchronize across time zones"), Category("Behavior"), Localizable(true), Bindable(true)] [Description("The text prompt for the UTC CheckBox.")] public string UTCPrompt { get { return utcPrompt; } set { if (utcPrompt != value) { utcPrompt = value; if (string.IsNullOrEmpty(utcPrompt)) { utcCheckBox.Checked = false; utcCheckBox.Visible = false; } else { utcCheckBox.Text = utcPrompt; utcCheckBox.Checked = false; utcCheckBox.Visible = true; } } } } /// /// Gets or sets the value. /// /// The value. [Category("Data"), RefreshProperties(RefreshProperties.All), Bindable(true), Description("The full date and time.")] public DateTime Value { get { return this.currentValue; } set { bool newVal = this.currentValue != value; if (newVal || !this.userHasSetValue) { this.currentValue = value; this.userHasSetValue = true; this.initializing = true; this.DataToControls(); this.initializing = false; if (newVal) OnValueChanged(EventArgs.Empty); } } } /// /// Gets a value indicating whether value is UTC. /// /// true if value is UTC; otherwise, false. [Browsable(false)] public bool ValueIsUTC { get { return this.currentValue.Kind == DateTimeKind.Utc; } } internal bool ShouldSerializeValue() { return this.userHasSetValue; } /// /// Raises the event. /// /// The instance containing the event data. protected virtual void OnValueChanged(EventArgs eventArgs) { EventHandler h = this.ValueChanged; if (h != null) h(this, EventArgs.Empty); } /// /// Selects the date control. /// protected void SelectDate() { this.dateTimePickerDate.Select(); } private void ControlsToData() { DateTime time = this.dateTimePickerDate.Value; if (timeFormat != FullDateTimePickerTimeFormat.Hidden) time += this.dateTimePickerTime.Value.TimeOfDay; if (!utcCheckBox.Checked) this.currentValue = DateTime.SpecifyKind(time, DateTimeKind.Unspecified); else { if (this.currentValue.Kind == DateTimeKind.Unspecified) { switch (utcBehavior) { case FieldConversionUtcCheckBehavior.ConvertLocalToUtc: this.currentValue = DateTime.SpecifyKind(time, DateTimeKind.Local).ToUniversalTime(); break; case FieldConversionUtcCheckBehavior.AssumeUtc: this.currentValue = DateTime.SpecifyKind(time, DateTimeKind.Utc); break; case FieldConversionUtcCheckBehavior.AssumeLocal: this.currentValue = DateTime.SpecifyKind(time, DateTimeKind.Local); break; default: break; } } else this.currentValue = DateTime.SpecifyKind(time, currentValue.Kind); } } private void DataToControls() { DateTime displayTime = this.currentValue.Kind == DateTimeKind.Utc ? this.currentValue.ToLocalTime() : this.currentValue; this.dateTimePickerDate.Value = displayTime.Date; this.dateTimePickerTime.Value = displayTime; if (!string.IsNullOrEmpty(utcPrompt)) this.utcCheckBox.Checked = this.currentValue.Kind != DateTimeKind.Unspecified; } private void FullDateTimePicker_Load(object sender, EventArgs e) { SetRightToLeft(); } private void FullDateTimePicker_RightToLeftChanged(object sender, EventArgs e) { SetRightToLeft(); } private void ResetValue() { this.Value = DateTime.Now; this.userHasSetValue = false; } private void SetRightToLeft() { RightToLeft rightToLeftProperty = this.RightToLeft; this.dateTimePickerDate.RightToLeft = rightToLeftProperty; this.dateTimePickerDate.RightToLeftLayout = rightToLeftProperty == RightToLeft.Yes; this.dateTimePickerTime.RightToLeft = rightToLeftProperty; this.dateTimePickerTime.RightToLeftLayout = rightToLeftProperty == RightToLeft.Yes; } private void subControl_ValueChanged(object sender, EventArgs e) { if (!initializing) { ControlsToData(); OnValueChanged(e); } } } }