Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / DatePicker.cs / 1305600 / DatePicker.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Windows; using System.Windows.Automation.Peers; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; using MS.Internal.KnownBoxes; namespace System.Windows.Controls { ////// Represents a control that allows the user to select a date. /// [TemplatePart(Name = DatePicker.ElementRoot, Type = typeof(Grid))] [TemplatePart(Name = DatePicker.ElementTextBox, Type = typeof(DatePickerTextBox))] [TemplatePart(Name = DatePicker.ElementButton, Type = typeof(Button))] [TemplatePart(Name = DatePicker.ElementPopup, Type = typeof(Popup))] public class DatePicker : Control { #region Constants private const string ElementRoot = "PART_Root"; private const string ElementTextBox = "PART_TextBox"; private const string ElementButton = "PART_Button"; private const string ElementPopup = "PART_Popup"; #endregion Constants #region Data private Calendar _calendar; private string _defaultText; private ButtonBase _dropDownButton; private Popup _popUp; private bool _disablePopupReopen; private DatePickerTextBox _textBox; private IDictionary_isHandlerSuspended; private DateTime? _originalSelectedDate; #endregion Data #region Public Events public static readonly RoutedEvent SelectedDateChangedEvent = EventManager.RegisterRoutedEvent("SelectedDateChanged", RoutingStrategy.Direct, typeof(EventHandler ), typeof(DatePicker)); /// /// Occurs when the drop-down Calendar is closed. /// public event RoutedEventHandler CalendarClosed; ////// Occurs when the drop-down Calendar is opened. /// public event RoutedEventHandler CalendarOpened; ////// Occurs when text entered into the DatePicker cannot be parsed or the Date is not valid to be selected. /// public event EventHandlerDateValidationError; /// /// Occurs when a date is selected. /// public event EventHandlerSelectedDateChanged { add { AddHandler(SelectedDateChangedEvent, value); } remove { RemoveHandler(SelectedDateChangedEvent, value); } } #endregion Public Events /// /// Static constructor /// static DatePicker() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DatePicker), new FrameworkPropertyMetadata(typeof(DatePicker))); EventManager.RegisterClassHandler(typeof(DatePicker), UIElement.GotFocusEvent, new RoutedEventHandler(OnGotFocus)); KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(DatePicker), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once)); KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(DatePicker), new FrameworkPropertyMetadata(false)); IsEnabledProperty.OverrideMetadata(typeof(DatePicker), new UIPropertyMetadata(new PropertyChangedCallback(OnIsEnabledChanged))); } ////// Initializes a new instance of the DatePicker class. /// public DatePicker() { InitializeCalendar(); this._defaultText = string.Empty; // Binding to FirstDayOfWeek and DisplayDate wont work this.SetCurrentValueInternal(FirstDayOfWeekProperty, DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek); this.DisplayDate = DateTime.Today; } #region Public properties #region BlackoutDates ////// Gets the days that are not selectable. /// public CalendarBlackoutDatesCollection BlackoutDates { get { return _calendar.BlackoutDates; } } #endregion BlackoutDates #region CalendarStyle ////// Gets or sets the style that is used when rendering the calendar. /// public Style CalendarStyle { get { return (Style)GetValue(CalendarStyleProperty); } set { SetValue(CalendarStyleProperty, value); } } ////// Identifies the CalendarStyle dependency property. /// public static readonly DependencyProperty CalendarStyleProperty = DependencyProperty.Register( "CalendarStyle", typeof(Style), typeof(DatePicker)); #endregion CalendarStyle #region DisplayDate ////// Gets or sets the date to display. /// /// public DateTime DisplayDate { get { return (DateTime)GetValue(DisplayDateProperty); } set { SetValue(DisplayDateProperty, value); } } ////// Identifies the DisplayDate dependency property. /// public static readonly DependencyProperty DisplayDateProperty = DependencyProperty.Register( "DisplayDate", typeof(DateTime), typeof(DatePicker), new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null, CoerceDisplayDate)); private static object CoerceDisplayDate(DependencyObject d, object value) { DatePicker dp = d as DatePicker; // We set _calendar.DisplayDate in order to get _calendar to compute the coerced value dp._calendar.DisplayDate = (DateTime)value; return dp._calendar.DisplayDate; } #endregion DisplayDate #region DisplayDateEnd ////// Gets or sets the last date to be displayed. /// /// public DateTime? DisplayDateEnd { get { return (DateTime?)GetValue(DisplayDateEndProperty); } set { SetValue(DisplayDateEndProperty, value); } } ////// Identifies the DisplayDateEnd dependency property. /// public static readonly DependencyProperty DisplayDateEndProperty = DependencyProperty.Register( "DisplayDateEnd", typeof(DateTime?), typeof(DatePicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDisplayDateEndChanged, CoerceDisplayDateEnd)); ////// DisplayDateEndProperty property changed handler. /// /// DatePicker that changed its DisplayDateEnd. /// DependencyPropertyChangedEventArgs. private static void OnDisplayDateEndChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); dp.CoerceValue(DisplayDateProperty); } private static object CoerceDisplayDateEnd(DependencyObject d, object value) { DatePicker dp = d as DatePicker; // We set _calendar.DisplayDateEnd in order to get _calendar to compute the coerced value dp._calendar.DisplayDateEnd = (DateTime?)value; return dp._calendar.DisplayDateEnd; } #endregion DisplayDateEnd #region DisplayDateStart ////// Gets or sets the first date to be displayed. /// /// public DateTime? DisplayDateStart { get { return (DateTime?)GetValue(DisplayDateStartProperty); } set { SetValue(DisplayDateStartProperty, value); } } ////// Identifies the DisplayDateStart dependency property. /// public static readonly DependencyProperty DisplayDateStartProperty = DependencyProperty.Register( "DisplayDateStart", typeof(DateTime?), typeof(DatePicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDisplayDateStartChanged, CoerceDisplayDateStart)); ////// DisplayDateStartProperty property changed handler. /// /// DatePicker that changed its DisplayDateStart. /// DependencyPropertyChangedEventArgs. private static void OnDisplayDateStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); dp.CoerceValue(DisplayDateEndProperty); dp.CoerceValue(DisplayDateProperty); } private static object CoerceDisplayDateStart(DependencyObject d, object value) { DatePicker dp = d as DatePicker; // We set _calendar.DisplayDateStart in order to get _calendar to compute the coerced value dp._calendar.DisplayDateStart = (DateTime?)value; return dp._calendar.DisplayDateStart; } #endregion DisplayDateStart #region FirstDayOfWeek ////// Gets or sets the day that is considered the beginning of the week. /// public DayOfWeek FirstDayOfWeek { get { return (DayOfWeek)GetValue(FirstDayOfWeekProperty); } set { SetValue(FirstDayOfWeekProperty, value); } } ////// Identifies the FirstDayOfWeek dependency property. /// public static readonly DependencyProperty FirstDayOfWeekProperty = DependencyProperty.Register( "FirstDayOfWeek", typeof(DayOfWeek), typeof(DatePicker), null, Calendar.IsValidFirstDayOfWeek); #endregion FirstDayOfWeek #region IsDropDownOpen ////// Gets or sets a value that indicates whether the drop-down Calendar is open or closed. /// public bool IsDropDownOpen { get { return (bool)GetValue(IsDropDownOpenProperty); } set { SetValue(IsDropDownOpenProperty, value); } } ////// Identifies the IsDropDownOpen dependency property. /// public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register( "IsDropDownOpen", typeof(bool), typeof(DatePicker), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsDropDownOpenChanged, OnCoerceIsDropDownOpen)); private static object OnCoerceIsDropDownOpen(DependencyObject d, object baseValue) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); if (!dp.IsEnabled) { return false; } return baseValue; } ////// IsDropDownOpenProperty property changed handler. /// /// DatePicker that changed its IsDropDownOpen. /// DependencyPropertyChangedEventArgs. private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); bool newValue = (bool)e.NewValue; if (dp._popUp != null && dp._popUp.IsOpen != newValue) { dp._popUp.IsOpen = newValue; if (newValue) { dp._originalSelectedDate = dp.SelectedDate; // When the popup is opened set focus to the DisplayDate button. // Do this asynchronously because the IsDropDownOpen could // have been set even before the template for the DatePicker is // applied. And this would mean that the visuals wouldn't be available yet. dp.Dispatcher.BeginInvoke(DispatcherPriority.Input, (Action)delegate() { // setting the focus to the calendar will focus the correct date. dp._calendar.Focus(); }); } } } private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); dp.CoerceValue(IsDropDownOpenProperty); OnVisualStatePropertyChanged(d, e); } #endregion IsDropDownOpen #region IsTodayHighlighted ////// Gets or sets a value that indicates whether the current date will be highlighted. /// public bool IsTodayHighlighted { get { return (bool)GetValue(IsTodayHighlightedProperty); } set { SetValue(IsTodayHighlightedProperty, value); } } ////// Identifies the IsTodayHighlighted dependency property. /// public static readonly DependencyProperty IsTodayHighlightedProperty = DependencyProperty.Register( "IsTodayHighlighted", typeof(bool), typeof(DatePicker)); #endregion IsTodayHighlighted #region SelectedDate ////// Gets or sets the currently selected date. /// /// public DateTime? SelectedDate { get { return (DateTime?)GetValue(SelectedDateProperty); } set { SetValue(SelectedDateProperty, value); } } ////// Identifies the SelectedDate dependency property. /// public static readonly DependencyProperty SelectedDateProperty = DependencyProperty.Register( "SelectedDate", typeof(DateTime?), typeof(DatePicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedDateChanged, CoerceSelectedDate)); ////// SelectedDateProperty property changed handler. /// /// DatePicker that changed its SelectedDate. /// DependencyPropertyChangedEventArgs. private static void OnSelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); CollectionaddedItems = new Collection (); Collection removedItems = new Collection (); DateTime? addedDate; DateTime? removedDate; dp.CoerceValue(DisplayDateStartProperty); dp.CoerceValue(DisplayDateEndProperty); dp.CoerceValue(DisplayDateProperty); addedDate = (DateTime?)e.NewValue; removedDate = (DateTime?)e.OldValue; if (dp.SelectedDate.HasValue) { DateTime day = dp.SelectedDate.Value; dp.SetTextInternal(dp.DateTimeToString(day)); // When DatePickerDisplayDateFlag is TRUE, the SelectedDate change is coming from the Calendar UI itself, // so, we shouldn't change the DisplayDate since it will automatically be changed by the Calendar if ((day.Month != dp.DisplayDate.Month || day.Year != dp.DisplayDate.Year) && !dp._calendar.DatePickerDisplayDateFlag) { dp.SetCurrentValueInternal(DisplayDateProperty, day); } dp._calendar.DatePickerDisplayDateFlag = false; } else { dp.SetWaterMarkText(); } if (addedDate.HasValue) { addedItems.Add(addedDate.Value); } if (removedDate.HasValue) { removedItems.Add(removedDate.Value); } dp.OnSelectedDateChanged(new CalendarSelectionChangedEventArgs(DatePicker.SelectedDateChangedEvent, removedItems, addedItems)); DatePickerAutomationPeer peer = UIElementAutomationPeer.FromElement(dp) as DatePickerAutomationPeer; // Raise the propetyChangeEvent for Value if Automation Peer exist if (peer != null) { string addedDateString = addedDate.HasValue ? dp.DateTimeToString(addedDate.Value) : ""; string removedDateString = removedDate.HasValue ? dp.DateTimeToString(removedDate.Value) : ""; peer.RaiseValuePropertyChangedEvent(removedDateString, addedDateString); } } private static object CoerceSelectedDate(DependencyObject d, object value) { DatePicker dp = d as DatePicker; // We set _calendar.SelectedDate in order to get _calendar to compute the coerced value dp._calendar.SelectedDate = (DateTime?)value; return dp._calendar.SelectedDate; } #endregion SelectedDate #region SelectedDateFormat /// /// Gets or sets the format that is used to display the selected date. /// public DatePickerFormat SelectedDateFormat { get { return (DatePickerFormat)GetValue(SelectedDateFormatProperty); } set { SetValue(SelectedDateFormatProperty, value); } } ////// Identifies the SelectedDateFormat dependency property. /// public static readonly DependencyProperty SelectedDateFormatProperty = DependencyProperty.Register( "SelectedDateFormat", typeof(DatePickerFormat), typeof(DatePicker), new FrameworkPropertyMetadata(DatePickerFormat.Long, OnSelectedDateFormatChanged), IsValidSelectedDateFormat); ////// SelectedDateFormatProperty property changed handler. /// /// DatePicker that changed its SelectedDateFormat. /// DependencyPropertyChangedEventArgs. private static void OnSelectedDateFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); if (dp._textBox != null) { // Update DatePickerTextBox.Text if (string.IsNullOrEmpty(dp._textBox.Text)) { dp.SetWaterMarkText(); } else { DateTime? date = dp.ParseText(dp._textBox.Text); if (date != null) { dp.SetTextInternal(dp.DateTimeToString((DateTime)date)); } } } } #endregion SelectedDateFormat #region Text ////// Gets or sets the text that is displayed by the DatePicker. /// public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } ////// Identifies the Text dependency property. /// public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof(string), typeof(DatePicker), new FrameworkPropertyMetadata(string.Empty, OnTextChanged)); ////// TextProperty property changed handler. /// /// DatePicker that changed its Text. /// DependencyPropertyChangedEventArgs. private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DatePicker dp = d as DatePicker; Debug.Assert(dp != null); if (!dp.IsHandlerSuspended(DatePicker.TextProperty)) { string newValue = e.NewValue as string; if (newValue != null) { if (dp._textBox != null) { dp._textBox.Text = newValue; } else { dp._defaultText = newValue; } dp.SetSelectedDate(); } else { dp.SetValueNoCallback(DatePicker.SelectedDateProperty, null); } } } ////// Sets the local Text property without breaking bindings /// /// private void SetTextInternal(string value) { SetCurrentValueInternal(TextProperty, value); } #endregion Text #endregion Public Properties #region Protected properties #endregion Protected Properties #region Internal Properties internal Calendar Calendar { get { return _calendar; } } internal TextBox TextBox { get { return _textBox; } } #endregion Internal Properties #region Private Properties #endregion Private Properties #region Public Methods ////// Builds the visual tree for the DatePicker control when a new template is applied. /// public override void OnApplyTemplate() { if (_popUp != null) { _popUp.RemoveHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(PopUp_PreviewMouseLeftButtonDown)); _popUp.Opened -= PopUp_Opened; _popUp.Closed -= PopUp_Closed; _popUp.Child = null; } if (_dropDownButton != null) { _dropDownButton.Click -= DropDownButton_Click; _dropDownButton.RemoveHandler(MouseLeaveEvent, new MouseEventHandler(DropDownButton_MouseLeave)); } if (_textBox != null) { _textBox.RemoveHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown)); _textBox.RemoveHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged)); _textBox.RemoveHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus)); } base.OnApplyTemplate(); _popUp = GetTemplateChild(ElementPopup) as Popup; if (_popUp != null) { _popUp.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(PopUp_PreviewMouseLeftButtonDown)); _popUp.Opened += PopUp_Opened; _popUp.Closed += PopUp_Closed; _popUp.Child = this._calendar; if (this.IsDropDownOpen) { this._popUp.IsOpen = true; } } _dropDownButton = GetTemplateChild(ElementButton) as Button; if (_dropDownButton != null) { _dropDownButton.Click += DropDownButton_Click; _dropDownButton.AddHandler(MouseLeaveEvent, new MouseEventHandler(DropDownButton_MouseLeave), true); // If the user does not provide a Content value in template, we provide a helper text that can be used in Accessibility // this text is not shown on the UI, just used for Accessibility purposes if (_dropDownButton.Content == null) { _dropDownButton.Content = SR.Get(SRID.DatePicker_DropDownButtonName); } } _textBox = GetTemplateChild(ElementTextBox) as DatePickerTextBox; if (this.SelectedDate == null) { SetWaterMarkText(); } if (_textBox != null) { _textBox.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown), true); _textBox.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged), true); _textBox.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(TextBox_LostFocus), true); if (this.SelectedDate == null) { if (!string.IsNullOrEmpty(this._defaultText)) { _textBox.Text = this._defaultText; SetSelectedDate(); } } else { _textBox.Text = this.DateTimeToString((DateTime)this.SelectedDate); } } } ////// Provides a text representation of the selected date. /// ///A text representation of the selected date, or an empty string if SelectedDate is a null reference. public override string ToString() { if (this.SelectedDate != null) { return this.SelectedDate.Value.ToString(DateTimeHelper.GetDateFormat(DateTimeHelper.GetCulture(this))); } else { return string.Empty; } } #endregion Public Methods #region Protected Methods internal override void ChangeVisualState(bool useTransitions) { if (!IsEnabled) { VisualStates.GoToState(this, useTransitions, VisualStates.StateDisabled, VisualStates.StateNormal); } else { VisualStateManager.GoToState(this, VisualStates.StateNormal, useTransitions); } base.ChangeVisualState(useTransitions); } ////// Creates the automation peer for this DatePicker Control. /// ///protected override AutomationPeer OnCreateAutomationPeer() { return new DatePickerAutomationPeer(this); } protected virtual void OnCalendarClosed(RoutedEventArgs e) { RoutedEventHandler handler = this.CalendarClosed; if (null != handler) { handler(this, e); } } protected virtual void OnCalendarOpened(RoutedEventArgs e) { RoutedEventHandler handler = this.CalendarOpened; if (null != handler) { handler(this, e); } } protected virtual void OnSelectedDateChanged(SelectionChangedEventArgs e) { RaiseEvent(e); } /// /// Raises the DateValidationError event. /// /// A DatePickerDateValidationErrorEventArgs that contains the event data. protected virtual void OnDateValidationError(DatePickerDateValidationErrorEventArgs e) { EventHandlerhandler = this.DateValidationError; if (handler != null) { handler(this, e); } } #endregion Protected Methods #region Private Methods /// /// Called when this element gets focus. /// private static void OnGotFocus(object sender, RoutedEventArgs e) { // When Datepicker gets focus move it to the TextBox DatePicker picker = (DatePicker)sender; if ((!e.Handled) && (picker._textBox != null)) { if (e.OriginalSource == picker) { picker._textBox.Focus(); e.Handled = true; } else if (e.OriginalSource == picker._textBox) { picker._textBox.SelectAll(); e.Handled = true; } } } private void SetValueNoCallback(DependencyProperty property, object value) { SetIsHandlerSuspended(property, true); try { SetCurrentValue(property, value); } finally { SetIsHandlerSuspended(property, false); } } private bool IsHandlerSuspended(DependencyProperty property) { return _isHandlerSuspended != null && _isHandlerSuspended.ContainsKey(property); } private void SetIsHandlerSuspended(DependencyProperty property, bool value) { if (value) { if (_isHandlerSuspended == null) { _isHandlerSuspended = new Dictionary(2); } _isHandlerSuspended[property] = true; } else { if (_isHandlerSuspended != null) { _isHandlerSuspended.Remove(property); } } } private void PopUp_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Popup popup = sender as Popup; if (popup != null && !popup.StaysOpen) { if (this._dropDownButton != null) { if (this._dropDownButton.InputHitTest(e.GetPosition(this._dropDownButton)) != null) { // This popup is being closed by a mouse press on the drop down button // The following mouse release will cause the closed popup to immediately reopen. // Raise a flag to block reopeneing the popup this._disablePopupReopen = true; } } } } private void PopUp_Opened(object sender, EventArgs e) { if (!this.IsDropDownOpen) { this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.TrueBox); } if (this._calendar != null) { this._calendar.DisplayMode = CalendarMode.Month; this._calendar.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); } this.OnCalendarOpened(new RoutedEventArgs()); } private void PopUp_Closed(object sender, EventArgs e) { if (this.IsDropDownOpen) { this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.FalseBox); } if (_calendar.IsKeyboardFocusWithin) { this.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); } OnCalendarClosed(new RoutedEventArgs()); } private void Calendar_DayButtonMouseUp(object sender, MouseButtonEventArgs e) { this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.FalseBox); } private void CalendarDayOrMonthButton_PreviewKeyDown(object sender, RoutedEventArgs e) { Calendar c = sender as Calendar; KeyEventArgs args = (KeyEventArgs)e; Debug.Assert(c != null); Debug.Assert(args != null); if (args.Key == Key.Escape || ((args.Key == Key.Enter || args.Key == Key.Space) && c.DisplayMode == CalendarMode.Month)) { this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.FalseBox); if (args.Key == Key.Escape) { SetCurrentValueInternal(SelectedDateProperty, _originalSelectedDate); } } } private void Calendar_DisplayDateChanged(object sender, CalendarDateChangedEventArgs e) { if (e.AddedDate != this.DisplayDate) { SetCurrentValueInternal(DisplayDateProperty, (DateTime)e.AddedDate); } } private void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e) { Debug.Assert(e.AddedItems.Count < 2); if (e.AddedItems.Count > 0 && this.SelectedDate.HasValue && DateTime.Compare((DateTime)e.AddedItems[0], this.SelectedDate.Value) != 0) { this.SetCurrentValueInternal(SelectedDateProperty, (DateTime?)e.AddedItems[0]); } else { if (e.AddedItems.Count == 0) { this.SetCurrentValueInternal(SelectedDateProperty, (DateTime?)null); return; } if (!this.SelectedDate.HasValue) { if (e.AddedItems.Count > 0) { this.SetCurrentValueInternal(SelectedDateProperty, (DateTime?)e.AddedItems[0]); } } } } private string DateTimeToString(DateTime d) { DateTimeFormatInfo dtfi = DateTimeHelper.GetDateFormat(DateTimeHelper.GetCulture(this)); switch (this.SelectedDateFormat) { case DatePickerFormat.Short: { return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.ShortDatePattern, dtfi)); } case DatePickerFormat.Long: { return string.Format(CultureInfo.CurrentCulture, d.ToString(dtfi.LongDatePattern, dtfi)); } } return null; } private static DateTime DiscardDayTime(DateTime d) { int year = d.Year; int month = d.Month; DateTime newD = new DateTime(year, month, 1, 0, 0, 0); return newD; } private static DateTime? DiscardTime(DateTime? d) { if (d == null) { return null; } else { DateTime discarded = (DateTime)d; int year = discarded.Year; int month = discarded.Month; int day = discarded.Day; DateTime newD = new DateTime(year, month, day, 0, 0, 0); return newD; } } private void DropDownButton_Click(object sender, RoutedEventArgs e) { TogglePopUp(); } private void DropDownButton_MouseLeave(object sender, MouseEventArgs e) { this._disablePopupReopen = false; } private void TogglePopUp() { if (this.IsDropDownOpen) { this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.FalseBox); } else { if (this._disablePopupReopen) { this._disablePopupReopen = false; } else { SetSelectedDate(); this.SetCurrentValueInternal(IsDropDownOpenProperty, BooleanBoxes.TrueBox); } } } private void InitializeCalendar() { _calendar = new Calendar(); _calendar.DayButtonMouseUp += new MouseButtonEventHandler(Calendar_DayButtonMouseUp); _calendar.DisplayDateChanged += new EventHandler (Calendar_DisplayDateChanged); _calendar.SelectedDatesChanged += new EventHandler (Calendar_SelectedDatesChanged); _calendar.DayOrMonthPreviewKeyDown += new RoutedEventHandler(CalendarDayOrMonthButton_PreviewKeyDown); _calendar.HorizontalAlignment = HorizontalAlignment.Left; _calendar.VerticalAlignment = VerticalAlignment.Top; _calendar.SelectionMode = CalendarSelectionMode.SingleDate; _calendar.SetBinding(Calendar.ForegroundProperty, GetDatePickerBinding(DatePicker.ForegroundProperty)); _calendar.SetBinding(Calendar.StyleProperty, GetDatePickerBinding(DatePicker.CalendarStyleProperty)); _calendar.SetBinding(Calendar.IsTodayHighlightedProperty, GetDatePickerBinding(DatePicker.IsTodayHighlightedProperty)); _calendar.SetBinding(Calendar.FirstDayOfWeekProperty, GetDatePickerBinding(DatePicker.FirstDayOfWeekProperty)); _calendar.SetBinding(Calendar.FlowDirectionProperty, GetDatePickerBinding(DatePicker.FlowDirectionProperty)); RenderOptions.SetClearTypeHint(_calendar, ClearTypeHint.Enabled); } private BindingBase GetDatePickerBinding(DependencyProperty property) { Binding binding = new Binding(property.Name); binding.Source = this; return binding; } private static bool IsValidSelectedDateFormat(object value) { DatePickerFormat format = (DatePickerFormat)value; return format == DatePickerFormat.Long || format == DatePickerFormat.Short; } // iT SHOULD RETURN NULL IF THE STRING IS NOT VALID, RETURN THE DATETIME VALUE IF IT IS VALID /// /// Input text is parsed in the correct format and changed into a DateTime object. /// If the text can not be parsed TextParseError Event is thrown. /// private DateTime? ParseText(string text) { DateTime newSelectedDate; // TryParse is not used in order to be able to pass the exception to the TextParseError event try { newSelectedDate = DateTime.Parse(text, DateTimeHelper.GetDateFormat(DateTimeHelper.GetCulture(this))); if (Calendar.IsValidDateSelection(this._calendar, newSelectedDate)) { return newSelectedDate; } else { DatePickerDateValidationErrorEventArgs dateValidationError = new DatePickerDateValidationErrorEventArgs(new ArgumentOutOfRangeException("text", SR.Get(SRID.Calendar_OnSelectedDateChanged_InvalidValue)), text); OnDateValidationError(dateValidationError); if (dateValidationError.ThrowException) { throw dateValidationError.Exception; } } } catch (FormatException ex) { DatePickerDateValidationErrorEventArgs textParseError = new DatePickerDateValidationErrorEventArgs(ex, text); OnDateValidationError(textParseError); if (textParseError.ThrowException && textParseError.Exception != null) { throw textParseError.Exception; } } return null; } private bool ProcessDatePickerKey(KeyEventArgs e) { switch (e.Key) { case Key.System: { switch (e.SystemKey) { case Key.Down: { if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) { TogglePopUp(); return true; } break; } } break; } case Key.Enter: { SetSelectedDate(); return true; } } return false; } private void SetSelectedDate() { if (this._textBox != null) { if (!string.IsNullOrEmpty(this._textBox.Text)) { string s = this._textBox.Text; if (this.SelectedDate != null) { // If the string value of the SelectedDate and the TextBox string value are equal, // we do not parse the string again // if we do an extra parse, we lose data in M/d/yy format // ex: SelectedDate = DateTime(1008,12,19) but when "12/19/08" is parsed it is interpreted as DateTime(2008,12,19) string selectedDate = DateTimeToString(this.SelectedDate.Value); if (string.Compare(selectedDate, s, StringComparison.Ordinal) == 0) { return; } } DateTime? d = SetTextBoxValue(s); if (!this.SelectedDate.Equals(d)) { this.SetCurrentValueInternal(SelectedDateProperty, d); this.SetCurrentValueInternal(DisplayDateProperty, d); } } else { if (this.SelectedDate.HasValue) { this.SetCurrentValueInternal(SelectedDateProperty, (DateTime?)null); } } } else { DateTime? d = SetTextBoxValue(_defaultText); if (!this.SelectedDate.Equals(d)) { this.SetCurrentValueInternal(SelectedDateProperty, d); } } } ////// Set the Text property if it's not already set to the supplied value. This avoids making the ValueSource Local. /// private void SafeSetText(string s) { if (string.Compare(Text, s, StringComparison.Ordinal) != 0) { SetCurrentValueInternal(TextProperty, s); } } private DateTime? SetTextBoxValue(string s) { if (string.IsNullOrEmpty(s)) { SafeSetText(s); return this.SelectedDate; } else { DateTime? d = ParseText(s); if (d != null) { SafeSetText(this.DateTimeToString((DateTime)d)); return d; } else { // If parse error: // TextBox should have the latest valid selecteddate value: if (this.SelectedDate != null) { string newtext = this.DateTimeToString((DateTime)this.SelectedDate); SafeSetText(newtext); return this.SelectedDate; } else { SetWaterMarkText(); return null; } } } } private void SetWaterMarkText() { if (this._textBox != null) { DateTimeFormatInfo dtfi = DateTimeHelper.GetDateFormat(DateTimeHelper.GetCulture(this)); this.SetTextInternal(string.Empty); this._defaultText = string.Empty; switch (this.SelectedDateFormat) { case DatePickerFormat.Long: { this._textBox.Watermark = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.DatePicker_WatermarkText), dtfi.LongDatePattern.ToString()); break; } case DatePickerFormat.Short: { this._textBox.Watermark = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.DatePicker_WatermarkText), dtfi.ShortDatePattern.ToString()); break; } } } } private void TextBox_LostFocus(object sender, RoutedEventArgs e) { SetSelectedDate(); } private void TextBox_KeyDown(object sender, KeyEventArgs e) { e.Handled = ProcessDatePickerKey(e) || e.Handled; } private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { this.SetValueNoCallback(DatePicker.TextProperty, this._textBox.Text); } #endregion Private Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HashHelper.cs
- TextTreeInsertUndoUnit.cs
- StackSpiller.cs
- VisualBasicSettings.cs
- ToolStripDropDownClosedEventArgs.cs
- HttpPostProtocolReflector.cs
- FocusWithinProperty.cs
- ObjectIDGenerator.cs
- GridViewColumnCollectionChangedEventArgs.cs
- HtmlInputFile.cs
- SqlClientMetaDataCollectionNames.cs
- DynamicObject.cs
- Vector3DValueSerializer.cs
- ChooseAction.cs
- PassportPrincipal.cs
- Typography.cs
- Html32TextWriter.cs
- DataException.cs
- XamlSerializationHelper.cs
- TemplateParser.cs
- Clock.cs
- UserCancellationException.cs
- TableParagraph.cs
- ObjectQuery.cs
- Processor.cs
- DataGridViewColumnTypePicker.cs
- StructuredTypeEmitter.cs
- EvidenceBase.cs
- MissingMemberException.cs
- WebPartManagerInternals.cs
- PLINQETWProvider.cs
- HttpCachePolicyWrapper.cs
- CodeTypeDeclaration.cs
- Size.cs
- CommandCollectionEditor.cs
- WinEventWrap.cs
- ObjectSet.cs
- EditBehavior.cs
- TextEndOfLine.cs
- JapaneseCalendar.cs
- CheckBox.cs
- Event.cs
- Viewport3DVisual.cs
- UrlPath.cs
- DataGridViewDataErrorEventArgs.cs
- GraphicsContainer.cs
- Operators.cs
- XmlCDATASection.cs
- SoapDocumentServiceAttribute.cs
- VectorCollectionConverter.cs
- MD5.cs
- DataGridViewRowConverter.cs
- Thumb.cs
- IdnMapping.cs
- TextPattern.cs
- TextSerializer.cs
- CollectionsUtil.cs
- DependencyProperty.cs
- KerberosReceiverSecurityToken.cs
- RuntimeHandles.cs
- FontFamilyValueSerializer.cs
- AdapterUtil.cs
- SpecialNameAttribute.cs
- AssociatedControlConverter.cs
- WindowsFormsSynchronizationContext.cs
- TrueReadOnlyCollection.cs
- DbInsertCommandTree.cs
- Crc32Helper.cs
- WSDualHttpSecurityMode.cs
- ColumnCollectionEditor.cs
- Events.cs
- DataBindingHandlerAttribute.cs
- MessageQueuePermissionAttribute.cs
- DiffuseMaterial.cs
- DateTimeConverter.cs
- DocumentViewer.cs
- Double.cs
- ProxyHelper.cs
- TextWriterEngine.cs
- PackageFilter.cs
- MultipartContentParser.cs
- MatrixTransform.cs
- ColorBlend.cs
- ErrorHandler.cs
- PathSegment.cs
- AppModelKnownContentFactory.cs
- CacheOutputQuery.cs
- ChangeConflicts.cs
- LastQueryOperator.cs
- UidPropertyAttribute.cs
- CodeNamespace.cs
- DetailsViewRowCollection.cs
- MetaTableHelper.cs
- Point3DCollectionConverter.cs
- TimeBoundedCache.cs
- ScriptingWebServicesSectionGroup.cs
- QilVisitor.cs
- ProcessHostServerConfig.cs
- FormClosedEvent.cs
- DetailsViewInsertEventArgs.cs