| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233 |
- // (c) Copyright Microsoft Corporation.
- // This source is subject to the Microsoft Public License (Ms-PL).
- // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
- // All other rights reserved.
- using System;
- using System.Diagnostics;
- using System.Globalization;
- using Avalonia.Data;
- using Avalonia.Input;
- using Avalonia.Interactivity;
- using Avalonia.Media;
- namespace Avalonia.Controls.Primitives
- {
- /// <summary>
- /// Represents the currently displayed month or year on a
- /// <see cref="T:Avalonia.Controls.Calendar" />.
- /// </summary>
- public sealed class CalendarItem : TemplatedControl
- {
- /// <summary>
- /// The number of days per week.
- /// </summary>
- private const int NumberOfDaysPerWeek = 7;
- private const string PART_ElementHeaderButton = "HeaderButton";
- private const string PART_ElementPreviousButton = "PreviousButton";
- private const string PART_ElementNextButton = "NextButton";
- private const string PART_ElementMonthView = "MonthView";
- private const string PART_ElementYearView = "YearView";
- private Button _headerButton;
- private Button _nextButton;
- private Button _previousButton;
- private Grid _monthView;
- private Grid _yearView;
- private ITemplate<IControl> _dayTitleTemplate;
- private CalendarButton _lastCalendarButton;
- private CalendarDayButton _lastCalendarDayButton;
-
- private DateTime _currentMonth;
- private bool _isMouseLeftButtonDown = false;
- private bool _isMouseLeftButtonDownYearView = false;
- private bool _isControlPressed = false;
- private System.Globalization.Calendar _calendar = new System.Globalization.GregorianCalendar();
- private PointerPressedEventArgs _downEventArg;
- private PointerPressedEventArgs _downEventArgYearView;
- internal Calendar Owner { get; set; }
- internal CalendarDayButton CurrentButton { get; set; }
- public static readonly StyledProperty<IBrush> HeaderBackgroundProperty = Calendar.HeaderBackgroundProperty.AddOwner<CalendarItem>();
- public IBrush HeaderBackground
- {
- get { return GetValue(HeaderBackgroundProperty); }
- set { SetValue(HeaderBackgroundProperty, value); }
- }
- public static readonly DirectProperty<CalendarItem, ITemplate<IControl>> DayTitleTemplateProperty =
- AvaloniaProperty.RegisterDirect<CalendarItem, ITemplate<IControl>>(
- nameof(DayTitleTemplate),
- o => o.DayTitleTemplate,
- (o,v) => o.DayTitleTemplate = v,
- defaultBindingMode: BindingMode.OneTime);
- public ITemplate<IControl> DayTitleTemplate
- {
- get { return _dayTitleTemplate; }
- set { SetAndRaise(DayTitleTemplateProperty, ref _dayTitleTemplate, value); }
- }
- /// <summary>
- /// Gets the button that allows switching between month mode, year mode,
- /// and decade mode.
- /// </summary>
- internal Button HeaderButton
- {
- get { return _headerButton; }
- private set
- {
- if (_headerButton != null)
- _headerButton.Click -= HeaderButton_Click;
- _headerButton = value;
- if (_headerButton != null)
- {
- _headerButton.Click += HeaderButton_Click;
- _headerButton.Focusable = false;
- }
- }
- }
- /// <summary>
- /// Gets the button that displays the next page of the calendar when it
- /// is clicked.
- /// </summary>
- internal Button NextButton
- {
- get { return _nextButton; }
- private set
- {
- if (_nextButton != null)
- _nextButton.Click -= NextButton_Click;
- _nextButton = value;
- if (_nextButton != null)
- {
- // 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 (_nextButton.Content == null)
- {
- _nextButton.Content = "next button";
- }
- _nextButton.IsVisible = true;
- _nextButton.Click += NextButton_Click;
- _nextButton.Focusable = false;
- }
- }
- }
- /// <summary>
- /// Gets the button that displays the previous page of the calendar when
- /// it is clicked.
- /// </summary>
- internal Button PreviousButton
- {
- get { return _previousButton; }
- private set
- {
- if (_previousButton != null)
- _previousButton.Click -= PreviousButton_Click;
- _previousButton = value;
- if (_previousButton != null)
- {
- // 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 (_previousButton.Content == null)
- {
- _previousButton.Content = "previous button";
- }
- _previousButton.IsVisible = true;
- _previousButton.Click += PreviousButton_Click;
- _previousButton.Focusable = false;
- }
- }
- }
- /// <summary>
- /// Gets the Grid that hosts the content when in month mode.
- /// </summary>
- internal Grid MonthView
- {
- get { return _monthView; }
- private set
- {
- if (_monthView != null)
- _monthView.PointerLeave -= MonthView_MouseLeave;
- _monthView = value;
- if (_monthView != null)
- _monthView.PointerLeave += MonthView_MouseLeave;
- }
- }
- /// <summary>
- /// Gets the Grid that hosts the content when in year or decade mode.
- /// </summary>
- internal Grid YearView
- {
- get { return _yearView; }
- private set
- {
- if (_yearView != null)
- _yearView.PointerLeave -= YearView_MouseLeave;
- _yearView = value;
- if (_yearView != null)
- _yearView.PointerLeave += YearView_MouseLeave;
- }
- }
- private void PopulateGrids()
- {
- if (MonthView != null)
- {
- for (int i = 0; i < Calendar.RowsPerMonth; i++)
- {
- if (_dayTitleTemplate != null)
- {
- var cell = _dayTitleTemplate.Build();
- cell.DataContext = string.Empty;
- cell.SetValue(Grid.RowProperty, 0);
- cell.SetValue(Grid.ColumnProperty, i);
- MonthView.Children.Add(cell);
- }
- }
- for (int i = 1; i < Calendar.RowsPerMonth; i++)
- {
- for (int j = 0; j < Calendar.ColumnsPerMonth; j++)
- {
- CalendarDayButton cell = new CalendarDayButton();
- if (Owner != null)
- {
- cell.Owner = Owner;
- }
- cell.SetValue(Grid.RowProperty, i);
- cell.SetValue(Grid.ColumnProperty, j);
- cell.CalendarDayButtonMouseDown += Cell_MouseLeftButtonDown;
- cell.CalendarDayButtonMouseUp += Cell_MouseLeftButtonUp;
- cell.PointerEnter += Cell_MouseEnter;
- cell.PointerLeave += Cell_MouseLeave;
- cell.Click += Cell_Click;
- MonthView.Children.Add(cell);
- }
- }
- }
- if (YearView != null)
- {
- CalendarButton month;
- for (int i = 0; i < Calendar.RowsPerYear; i++)
- {
- for (int j = 0; j < Calendar.ColumnsPerYear; j++)
- {
- month = new CalendarButton();
- if (Owner != null)
- {
- month.Owner = Owner;
- }
- month.SetValue(Grid.RowProperty, i);
- month.SetValue(Grid.ColumnProperty, j);
- month.CalendarLeftMouseButtonDown += Month_CalendarButtonMouseDown;
- month.CalendarLeftMouseButtonUp += Month_CalendarButtonMouseUp;
- month.PointerEnter += Month_MouseEnter;
- month.PointerLeave += Month_MouseLeave;
- YearView.Children.Add(month);
- }
- }
- }
- }
- /// <summary>
- /// Builds the visual tree for the
- /// <see cref="T:System.Windows.Controls.Primitives.CalendarItem" />
- /// when a new template is applied.
- /// </summary>
- protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
- {
- base.OnTemplateApplied(e);
-
- HeaderButton = e.NameScope.Find<Button>(PART_ElementHeaderButton);
- PreviousButton = e.NameScope.Find<Button>(PART_ElementPreviousButton);
- NextButton = e.NameScope.Find<Button>(PART_ElementNextButton);
- MonthView = e.NameScope.Find<Grid>(PART_ElementMonthView);
- YearView = e.NameScope.Find<Grid>(PART_ElementYearView);
-
- if (Owner != null)
- {
- UpdateDisabled(Owner.IsEnabled);
- }
- PopulateGrids();
- if (MonthView != null && YearView != null)
- {
- if (Owner != null)
- {
- Owner.SelectedMonth = Owner.DisplayDateInternal;
- Owner.SelectedYear = Owner.DisplayDateInternal;
- if (Owner.DisplayMode == CalendarMode.Year)
- {
- UpdateYearMode();
- }
- else if (Owner.DisplayMode == CalendarMode.Decade)
- {
- UpdateDecadeMode();
- }
- if (Owner.DisplayMode == CalendarMode.Month)
- {
- UpdateMonthMode();
- MonthView.IsVisible = true;
- YearView.IsVisible = false;
- }
- else
- {
- YearView.IsVisible = true;
- MonthView.IsVisible = false;
- }
- }
- else
- {
- UpdateMonthMode();
- MonthView.IsVisible = true;
- YearView.IsVisible = false;
- }
- }
- }
- private void SetDayTitles()
- {
- for (int childIndex = 0; childIndex < Calendar.ColumnsPerMonth; childIndex++)
- {
- var daytitle = MonthView.Children[childIndex];
- if (daytitle != null)
- {
- if (Owner != null)
- {
- daytitle.DataContext = DateTimeHelper.GetCurrentDateFormat().ShortestDayNames[(childIndex + (int)Owner.FirstDayOfWeek) % NumberOfDaysPerWeek];
- }
- else
- {
- daytitle.DataContext = DateTimeHelper.GetCurrentDateFormat().ShortestDayNames[(childIndex + (int)DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek) % NumberOfDaysPerWeek];
- }
- }
- }
- }
- /// <summary>
- /// How many days of the previous month need to be displayed.
- /// </summary>
- private int PreviousMonthDays(DateTime firstOfMonth)
- {
- DayOfWeek day = _calendar.GetDayOfWeek(firstOfMonth);
- int i;
- if (Owner != null)
- {
- i = ((day - Owner.FirstDayOfWeek + NumberOfDaysPerWeek) % NumberOfDaysPerWeek);
- }
- else
- {
- i = ((day - DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek + NumberOfDaysPerWeek) % NumberOfDaysPerWeek);
- }
- if (i == 0)
- {
- return NumberOfDaysPerWeek;
- }
- else
- {
- return i;
- }
- }
- internal void UpdateMonthMode()
- {
- if (Owner != null)
- {
- Debug.Assert(Owner.DisplayDate != null, "The Owner Calendar's DisplayDate should not be null!");
- _currentMonth = Owner.DisplayDateInternal;
- }
- else
- {
- _currentMonth = DateTime.Today;
- }
- if (_currentMonth != null)
- {
- SetMonthModeHeaderButton();
- SetMonthModePreviousButton(_currentMonth);
- SetMonthModeNextButton(_currentMonth);
- if (MonthView != null)
- {
- SetDayTitles();
- SetCalendarDayButtons(_currentMonth);
- }
- }
- }
- private void SetMonthModeHeaderButton()
- {
- if (HeaderButton != null)
- {
- if (Owner != null)
- {
- HeaderButton.Content = Owner.DisplayDateInternal.ToString("Y", DateTimeHelper.GetCurrentDateFormat());
- HeaderButton.IsEnabled = true;
- }
- else
- {
- HeaderButton.Content = DateTime.Today.ToString("Y", DateTimeHelper.GetCurrentDateFormat());
- }
- }
- }
- private void SetMonthModeNextButton(DateTime firstDayOfMonth)
- {
- if (Owner != null && NextButton != null)
- {
- // DisplayDate is equal to DateTime.MaxValue
- if (DateTimeHelper.CompareYearMonth(firstDayOfMonth, DateTime.MaxValue) == 0)
- {
- NextButton.IsEnabled = false;
- }
- else
- {
- // Since we are sure DisplayDate is not equal to
- // DateTime.MaxValue, it is safe to use AddMonths
- DateTime firstDayOfNextMonth = _calendar.AddMonths(firstDayOfMonth, 1);
- NextButton.IsEnabled = (DateTimeHelper.CompareDays(Owner.DisplayDateRangeEnd, firstDayOfNextMonth) > -1);
- }
- }
- }
- private void SetMonthModePreviousButton(DateTime firstDayOfMonth)
- {
- if (Owner != null && PreviousButton != null)
- {
- PreviousButton.IsEnabled = (DateTimeHelper.CompareDays(Owner.DisplayDateRangeStart, firstDayOfMonth) < 0);
- }
- }
- private void SetButtonState(CalendarDayButton childButton, DateTime dateToAdd)
- {
- if (Owner != null)
- {
- childButton.Opacity = 1;
- // If the day is outside the DisplayDateStart/End boundary, do
- // not show it
- if (DateTimeHelper.CompareDays(dateToAdd, Owner.DisplayDateRangeStart) < 0 || DateTimeHelper.CompareDays(dateToAdd, Owner.DisplayDateRangeEnd) > 0)
- {
- childButton.IsEnabled = false;
- childButton.IsToday = false;
- childButton.IsSelected = false;
- childButton.Opacity = 0;
- }
- else
- {
- // SET IF THE DAY IS SELECTABLE OR NOT
- if (Owner.BlackoutDates.Contains(dateToAdd))
- {
- childButton.IsBlackout = true;
- }
- else
- {
- childButton.IsBlackout = false;
- }
- childButton.IsEnabled = true;
- // SET IF THE DAY IS INACTIVE OR NOT: set if the day is a
- // trailing day or not
- childButton.IsInactive = (DateTimeHelper.CompareYearMonth(dateToAdd, Owner.DisplayDateInternal) != 0);
- // SET IF THE DAY IS TODAY OR NOT
- childButton.IsToday = (Owner.IsTodayHighlighted && dateToAdd == DateTime.Today);
- // SET IF THE DAY IS SELECTED OR NOT
- childButton.IsSelected = false;
- foreach (DateTime item in Owner.SelectedDates)
- {
- // Since we should be comparing the Date values not
- // DateTime values, we can't use
- // Owner.SelectedDates.Contains(dateToAdd) directly
- childButton.IsSelected |= (DateTimeHelper.CompareDays(dateToAdd, item) == 0);
- }
- // SET THE FOCUS ELEMENT
- if (Owner.LastSelectedDate != null)
- {
- if (DateTimeHelper.CompareDays(Owner.LastSelectedDate.Value, dateToAdd) == 0)
- {
- if (Owner.FocusButton != null)
- {
- Owner.FocusButton.IsCurrent = false;
- }
- Owner.FocusButton = childButton;
- if (Owner.HasFocusInternal)
- {
- Owner.FocusButton.IsCurrent = true;
- }
- }
- else
- {
- childButton.IsCurrent = false;
- }
- }
- }
- }
- }
- private void SetCalendarDayButtons(DateTime firstDayOfMonth)
- {
- int lastMonthToDisplay = PreviousMonthDays(firstDayOfMonth);
- DateTime dateToAdd;
- if (DateTimeHelper.CompareYearMonth(firstDayOfMonth, DateTime.MinValue) > 0)
- {
- // DisplayDate is not equal to DateTime.MinValue we can subtract
- // days from the DisplayDate
- dateToAdd = _calendar.AddDays(firstDayOfMonth, -lastMonthToDisplay);
- }
- else
- {
- dateToAdd = firstDayOfMonth;
- }
- if (Owner != null && Owner.HoverEnd != null && Owner.HoverStart != null)
- {
- Owner.HoverEndIndex = null;
- Owner.HoverStartIndex = null;
- }
- int count = Calendar.RowsPerMonth * Calendar.ColumnsPerMonth;
- for (int childIndex = Calendar.ColumnsPerMonth; childIndex < count; childIndex++)
- {
- CalendarDayButton childButton = MonthView.Children[childIndex] as CalendarDayButton;
- Contract.Requires<ArgumentNullException>(childButton != null);
- childButton.Index = childIndex;
- SetButtonState(childButton, dateToAdd);
- // Update the indexes of hoverStart and hoverEnd
- if (Owner != null && Owner.HoverEnd != null && Owner.HoverStart != null)
- {
- if (DateTimeHelper.CompareDays(dateToAdd, Owner.HoverEnd.Value) == 0)
- {
- Owner.HoverEndIndex = childIndex;
- }
- if (DateTimeHelper.CompareDays(dateToAdd, Owner.HoverStart.Value) == 0)
- {
- Owner.HoverStartIndex = childIndex;
- }
- }
- //childButton.Focusable = false;
- childButton.Content = dateToAdd.Day.ToString(DateTimeHelper.GetCurrentDateFormat());
- childButton.DataContext = dateToAdd;
- if (DateTime.Compare((DateTime)DateTimeHelper.DiscardTime(DateTime.MaxValue), dateToAdd) > 0)
- {
- // Since we are sure DisplayDate is not equal to
- // DateTime.MaxValue, it is safe to use AddDays
- dateToAdd = _calendar.AddDays(dateToAdd, 1);
- }
- else
- {
- // DisplayDate is equal to the DateTime.MaxValue, so there
- // are no trailing days
- childIndex++;
- for (int i = childIndex; i < count; i++)
- {
- childButton = MonthView.Children[i] as CalendarDayButton;
- Contract.Requires<ArgumentNullException>(childButton != null);
- // button needs a content to occupy the necessary space
- // for the content presenter
- childButton.Content = i.ToString(DateTimeHelper.GetCurrentDateFormat());
- childButton.IsEnabled = false;
- childButton.Opacity = 0;
- }
- return;
- }
- }
- // If the HoverStart or HoverEndInternal could not be found on the
- // DisplayMonth set the values of the HoverStartIndex or
- // HoverEndIndex to be the first or last day indexes on the current
- // month
- if (Owner != null && Owner.HoverStart.HasValue && Owner.HoverEndInternal.HasValue)
- {
- if (!Owner.HoverEndIndex.HasValue)
- {
- if (DateTimeHelper.CompareDays(Owner.HoverEndInternal.Value, Owner.HoverStart.Value) > 0)
- {
- Owner.HoverEndIndex = Calendar.ColumnsPerMonth * Calendar.RowsPerMonth - 1;
- }
- else
- {
- Owner.HoverEndIndex = Calendar.ColumnsPerMonth;
- }
- }
- if (!Owner.HoverStartIndex.HasValue)
- {
- if (DateTimeHelper.CompareDays(Owner.HoverEndInternal.Value, Owner.HoverStart.Value) > 0)
- {
- Owner.HoverStartIndex = Calendar.ColumnsPerMonth;
- }
- else
- {
- Owner.HoverStartIndex = Calendar.ColumnsPerMonth * Calendar.RowsPerMonth - 1;
- }
- }
- }
- }
- internal void UpdateYearMode()
- {
- if (Owner != null)
- {
- Debug.Assert(Owner.SelectedMonth != null, "The Owner Calendar's SelectedMonth should not be null!");
- _currentMonth = (DateTime)Owner.SelectedMonth;
- }
- else
- {
- _currentMonth = DateTime.Today;
- }
- if (_currentMonth != null)
- {
- SetYearModeHeaderButton();
- SetYearModePreviousButton();
- SetYearModeNextButton();
- if (YearView != null)
- {
- SetMonthButtonsForYearMode();
- }
- }
- }
- private void SetYearModeHeaderButton()
- {
- if (HeaderButton != null)
- {
- HeaderButton.IsEnabled = true;
- HeaderButton.Content = _currentMonth.Year.ToString(DateTimeHelper.GetCurrentDateFormat());
- }
- }
- private void SetYearModePreviousButton()
- {
- if (Owner != null && PreviousButton != null)
- {
- PreviousButton.IsEnabled = (Owner.DisplayDateRangeStart.Year != _currentMonth.Year);
- }
- }
- private void SetYearModeNextButton()
- {
- if (Owner != null && NextButton != null)
- {
- NextButton.IsEnabled = (Owner.DisplayDateRangeEnd.Year != _currentMonth.Year);
- }
- }
- private void SetMonthButtonsForYearMode()
- {
- int count = 0;
- foreach (object child in YearView.Children)
- {
- CalendarButton childButton = child as CalendarButton;
- Contract.Requires<ArgumentNullException>(childButton != null);
- // There should be no time component. Time is 12:00 AM
- DateTime day = new DateTime(_currentMonth.Year, count + 1, 1);
- childButton.DataContext = day;
- childButton.Content = DateTimeHelper.GetCurrentDateFormat().AbbreviatedMonthNames[count];
- childButton.IsVisible = true;
- if (Owner != null)
- {
- if (day.Year == _currentMonth.Year && day.Month == _currentMonth.Month && day.Day == _currentMonth.Day)
- {
- Owner.FocusCalendarButton = childButton;
- childButton.IsCalendarButtonFocused = Owner.HasFocusInternal;
- }
- else
- {
- childButton.IsCalendarButtonFocused = false;
- }
- Debug.Assert(Owner.DisplayDateInternal != null, "The Owner Calendar's DisplayDateInternal should not be null!");
- childButton.IsSelected = (DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateInternal) == 0);
- if (DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateRangeStart) < 0 || DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateRangeEnd) > 0)
- {
- childButton.IsEnabled = false;
- childButton.Opacity = 0;
- }
- else
- {
- childButton.IsEnabled = true;
- childButton.Opacity = 1;
- }
- }
- childButton.IsInactive = false;
- count++;
- }
- }
- internal void UpdateDecadeMode()
- {
- DateTime selectedYear;
- if (Owner != null)
- {
- Debug.Assert(Owner.SelectedYear != null, "The owning Calendar's selected year should not be null!");
- selectedYear = Owner.SelectedYear;
- _currentMonth = (DateTime)Owner.SelectedMonth;
- }
- else
- {
- _currentMonth = DateTime.Today;
- selectedYear = DateTime.Today;
- }
- if (_currentMonth != null)
- {
- int decade = DateTimeHelper.DecadeOfDate(selectedYear);
- int decadeEnd = DateTimeHelper.EndOfDecade(selectedYear);
- SetDecadeModeHeaderButton(decade, decadeEnd);
- SetDecadeModePreviousButton(decade);
- SetDecadeModeNextButton(decadeEnd);
- if (YearView != null)
- {
- SetYearButtons(decade, decadeEnd);
- }
- }
- }
- internal void UpdateYearViewSelection(CalendarButton calendarButton)
- {
- if (Owner != null && calendarButton != null && calendarButton.DataContext != null)
- {
- Owner.FocusCalendarButton.IsCalendarButtonFocused = false;
- Owner.FocusCalendarButton = calendarButton;
- calendarButton.IsCalendarButtonFocused = Owner.HasFocusInternal;
- if (Owner.DisplayMode == CalendarMode.Year)
- {
- Owner.SelectedMonth = (DateTime)calendarButton.DataContext;
- }
- else
- {
- Owner.SelectedYear = (DateTime)calendarButton.DataContext;
- }
- }
- }
- private void SetYearButtons(int decade, int decadeEnd)
- {
- int year;
- int count = -1;
- foreach (object child in YearView.Children)
- {
- CalendarButton childButton = child as CalendarButton;
- Contract.Requires<ArgumentNullException>(childButton != null);
- year = decade + count;
- if (year <= DateTime.MaxValue.Year && year >= DateTime.MinValue.Year)
- {
- // There should be no time component. Time is 12:00 AM
- DateTime day = new DateTime(year, 1, 1);
- childButton.DataContext = day;
- childButton.Content = year.ToString(DateTimeHelper.GetCurrentDateFormat());
- childButton.IsVisible = true;
- if (Owner != null)
- {
- if (year == Owner.SelectedYear.Year)
- {
- Owner.FocusCalendarButton = childButton;
- childButton.IsCalendarButtonFocused = Owner.HasFocusInternal;
- }
- else
- {
- childButton.IsCalendarButtonFocused = false;
- }
- childButton.IsSelected = (Owner.DisplayDate.Year == year);
- if (year < Owner.DisplayDateRangeStart.Year || year > Owner.DisplayDateRangeEnd.Year)
- {
- childButton.IsEnabled = false;
- childButton.Opacity = 0;
- }
- else
- {
- childButton.IsEnabled = true;
- childButton.Opacity = 1;
- }
- }
- // SET IF THE YEAR IS INACTIVE OR NOT: set if the year is a
- // trailing year or not
- childButton.IsInactive = (year < decade || year > decadeEnd);
- }
- else
- {
- childButton.IsEnabled = false;
- childButton.Opacity = 0;
- }
- count++;
- }
- }
- private void SetDecadeModeHeaderButton(int decade, int decadeEnd)
- {
- if (HeaderButton != null)
- {
- HeaderButton.Content = decade.ToString(CultureInfo.CurrentCulture) + "-" + decadeEnd.ToString(CultureInfo.CurrentCulture);
- HeaderButton.IsEnabled = false;
- }
- }
- private void SetDecadeModeNextButton(int decadeEnd)
- {
- if (Owner != null && NextButton != null)
- {
- NextButton.IsEnabled = (Owner.DisplayDateRangeEnd.Year > decadeEnd);
- }
- }
- private void SetDecadeModePreviousButton(int decade)
- {
- if (Owner != null && PreviousButton != null)
- {
- PreviousButton.IsEnabled = (decade > Owner.DisplayDateRangeStart.Year);
- }
- }
- internal void HeaderButton_Click(object sender, RoutedEventArgs e)
- {
- if (Owner != null)
- {
- if (!Owner.HasFocusInternal)
- {
- Owner.Focus();
- }
- Button b = (Button)sender;
- DateTime d;
- if (b.IsEnabled)
- {
- if (Owner.DisplayMode == CalendarMode.Month)
- {
- if (Owner.DisplayDate != null)
- {
- d = Owner.DisplayDateInternal;
- Owner.SelectedMonth = new DateTime(d.Year, d.Month, 1);
- }
- Owner.DisplayMode = CalendarMode.Year;
- }
- else
- {
- Debug.Assert(Owner.DisplayMode == CalendarMode.Year, "The Owner Calendar's DisplayMode should be Year!");
- if (Owner.SelectedMonth != null)
- {
- d = Owner.SelectedMonth;
- Owner.SelectedYear = new DateTime(d.Year, d.Month, 1);
- }
- Owner.DisplayMode = CalendarMode.Decade;
- }
- }
- }
- }
- internal void PreviousButton_Click(object sender, RoutedEventArgs e)
- {
- if (Owner != null)
- {
- if (!Owner.HasFocusInternal)
- {
- Owner.Focus();
- }
- Button b = (Button)sender;
- if (b.IsEnabled)
- {
- Owner.OnPreviousClick();
- }
- }
- }
- internal void NextButton_Click(object sender, RoutedEventArgs e)
- {
- if (Owner != null)
- {
- if (!Owner.HasFocusInternal)
- {
- Owner.Focus();
- }
- Button b = (Button)sender;
- if (b.IsEnabled)
- {
- Owner.OnNextClick();
- }
- }
- }
- internal void Cell_MouseEnter(object sender, PointerEventArgs e)
- {
- if (Owner != null)
- {
- if (_isMouseLeftButtonDown && sender is CalendarDayButton b && b.IsEnabled && !b.IsBlackout)
- {
- // Update the states of all buttons to be selected starting
- // from HoverStart to b
- switch (Owner.SelectionMode)
- {
- case CalendarSelectionMode.SingleDate:
- {
- DateTime selectedDate = (DateTime)b.DataContext;
- Owner.DatePickerDisplayDateFlag = true;
- if (Owner.SelectedDates.Count == 0)
- {
- Owner.SelectedDates.Add(selectedDate);
- }
- else
- {
- Owner.SelectedDates[0] = selectedDate;
- }
- return;
- }
- case CalendarSelectionMode.SingleRange:
- case CalendarSelectionMode.MultipleRange:
- {
- Debug.Assert(b.DataContext != null, "The DataContext should not be null!");
- Owner.UnHighlightDays();
- Owner.HoverEndIndex = b.Index;
- Owner.HoverEnd = (DateTime?)b.DataContext;
- // Update the States of the buttons
- Owner.HighlightDays();
- return;
- }
- }
- }
- }
- }
- internal void Cell_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_isMouseLeftButtonDown)
- {
- CalendarDayButton b = (CalendarDayButton)sender;
- // The button is in Pressed state. Change the state to normal.
- if (e.Device.Captured == b)
- e.Device.Capture(null);
- _lastCalendarDayButton = b;
- }
- }
- internal void Cell_MouseLeftButtonDown(object sender, PointerPressedEventArgs e)
- {
- if (Owner != null)
- {
- if (!Owner.HasFocusInternal)
- {
- Owner.Focus();
- }
- bool ctrl, shift;
- CalendarExtensions.GetMetaKeyState(e.InputModifiers, out ctrl, out shift);
- CalendarDayButton b = sender as CalendarDayButton;
- if (b != null)
- {
- _isControlPressed = ctrl;
- if (b.IsEnabled && !b.IsBlackout)
- {
- DateTime selectedDate = (DateTime)b.DataContext;
- Contract.Requires<ArgumentNullException>(selectedDate != null);
- _isMouseLeftButtonDown = true;
- // null check is added for unit tests
- if (e != null)
- {
- _downEventArg = e;
- }
- switch (Owner.SelectionMode)
- {
- case CalendarSelectionMode.None:
- {
- return;
- }
- case CalendarSelectionMode.SingleDate:
- {
- Owner.DatePickerDisplayDateFlag = true;
- if (Owner.SelectedDates.Count == 0)
- {
- Owner.SelectedDates.Add(selectedDate);
- }
- else
- {
- Owner.SelectedDates[0] = selectedDate;
- }
- return;
- }
- case CalendarSelectionMode.SingleRange:
- {
- // Set the start or end of the selection
- // range
- if (shift)
- {
- Owner.UnHighlightDays();
- Owner.HoverEnd = selectedDate;
- Owner.HoverEndIndex = b.Index;
- Owner.HighlightDays();
- }
- else
- {
- Owner.UnHighlightDays();
- Owner.HoverStart = selectedDate;
- Owner.HoverStartIndex = b.Index;
- }
- return;
- }
- case CalendarSelectionMode.MultipleRange:
- {
- if (shift)
- {
- if (!ctrl)
- {
- // clear the list, set the states to
- // default
- foreach (DateTime item in Owner.SelectedDates)
- {
- Owner.RemovedItems.Add(item);
- }
- Owner.SelectedDates.ClearInternal();
- }
- Owner.HoverEnd = selectedDate;
- Owner.HoverEndIndex = b.Index;
- Owner.HighlightDays();
- }
- else
- {
- if (!ctrl)
- {
- // clear the list, set the states to
- // default
- foreach (DateTime item in Owner.SelectedDates)
- {
- Owner.RemovedItems.Add(item);
- }
- Owner.SelectedDates.ClearInternal();
- Owner.UnHighlightDays();
- }
- Owner.HoverStart = selectedDate;
- Owner.HoverStartIndex = b.Index;
- }
- return;
- }
- }
- }
- else
- {
- // If a click occurs on a BlackOutDay we set the
- // HoverStart to be null
- Owner.HoverStart = null;
- }
- }
- else
- {
- _isControlPressed = false;
- }
- }
- }
- private void AddSelection(CalendarDayButton b)
- {
- if (Owner != null)
- {
- Owner.HoverEndIndex = b.Index;
- Owner.HoverEnd = (DateTime)b.DataContext;
- if (Owner.HoverEnd != null && Owner.HoverStart != null)
- {
- // this is selection with Mouse, we do not guarantee the
- // range does not include BlackOutDates. AddRange method
- // will throw away the BlackOutDates based on the
- // SelectionMode
- Owner.IsMouseSelection = true;
- Owner.SelectedDates.AddRange(Owner.HoverStart.Value, Owner.HoverEnd.Value);
- Owner.OnDayClick((DateTime)b.DataContext);
- }
- }
- }
- internal void Cell_MouseLeftButtonUp(object sender, PointerReleasedEventArgs e)
- {
- if (Owner != null)
- {
- CalendarDayButton b = sender as CalendarDayButton;
- if (b != null && !b.IsBlackout)
- {
- Owner.OnDayButtonMouseUp(e);
- }
- _isMouseLeftButtonDown = false;
- if (b != null && b.DataContext != null)
- {
- if (Owner.SelectionMode == CalendarSelectionMode.None || Owner.SelectionMode == CalendarSelectionMode.SingleDate)
- {
- Owner.OnDayClick((DateTime)b.DataContext);
- return;
- }
- if (Owner.HoverStart.HasValue)
- {
- switch (Owner.SelectionMode)
- {
- case CalendarSelectionMode.SingleRange:
- {
- // Update SelectedDates
- foreach (DateTime item in Owner.SelectedDates)
- {
- Owner.RemovedItems.Add(item);
- }
- Owner.SelectedDates.ClearInternal();
- AddSelection(b);
- return;
- }
- case CalendarSelectionMode.MultipleRange:
- {
- // add the selection (either single day or
- // SingleRange day)
- AddSelection(b);
- return;
- }
- }
- }
- else
- {
- // If the day is Disabled but a trailing day we should
- // be able to switch months
- if (b.IsInactive && b.IsBlackout)
- {
- Owner.OnDayClick((DateTime)b.DataContext);
- }
- }
- }
- }
- }
- private void Cell_Click(object sender, RoutedEventArgs e)
- {
- if (Owner != null)
- {
- if (_isControlPressed && Owner.SelectionMode == CalendarSelectionMode.MultipleRange)
- {
- CalendarDayButton b = sender as CalendarDayButton;
- Contract.Requires<ArgumentNullException>(b != null);
- if (b.IsSelected)
- {
- Owner.HoverStart = null;
- _isMouseLeftButtonDown = false;
- b.IsSelected = false;
- if (b.DataContext != null)
- {
- Owner.SelectedDates.Remove((DateTime)b.DataContext);
- }
- }
- }
- }
- _isControlPressed = false;
- }
- private void Month_CalendarButtonMouseDown(object sender, PointerPressedEventArgs e)
- {
- CalendarButton b = sender as CalendarButton;
- Contract.Requires<ArgumentNullException>(b != null);
- _isMouseLeftButtonDownYearView = true;
- if (e != null)
- {
- _downEventArgYearView = e;
- }
- UpdateYearViewSelection(b);
- }
- internal void Month_CalendarButtonMouseUp(object sender, PointerReleasedEventArgs e)
- {
- _isMouseLeftButtonDownYearView = false;
- if (Owner != null)
- {
- DateTime newmonth = (DateTime)((CalendarButton)sender).DataContext;
- if (Owner.DisplayMode == CalendarMode.Year)
- {
- Owner.DisplayDate = newmonth;
- Owner.DisplayMode = CalendarMode.Month;
- }
- else
- {
- Debug.Assert(Owner.DisplayMode == CalendarMode.Decade, "The owning Calendar should be in decade mode!");
- Owner.SelectedMonth = newmonth;
- Owner.DisplayMode = CalendarMode.Year;
- }
- }
- }
- private void Month_MouseEnter(object sender, PointerEventArgs e)
- {
- if (_isMouseLeftButtonDownYearView)
- {
- CalendarButton b = sender as CalendarButton;
- Contract.Requires<ArgumentNullException>(b != null);
- UpdateYearViewSelection(b);
- }
- }
- private void Month_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_isMouseLeftButtonDownYearView)
- {
- CalendarButton b = (CalendarButton)sender;
- // The button is in Pressed state. Change the state to normal.
- if (e.Device.Captured == b)
- e.Device.Capture(null);
- //b.ReleaseMouseCapture();
- _lastCalendarButton = b;
- }
- }
- private void MonthView_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_lastCalendarDayButton != null)
- {
- e.Device.Capture(_lastCalendarDayButton);
- }
- }
- private void YearView_MouseLeave(object sender, PointerEventArgs e)
- {
- if (_lastCalendarButton != null)
- {
- e.Device.Capture(_lastCalendarButton);
- }
- }
-
- internal void UpdateDisabled(bool isEnabled)
- {
- PseudoClasses.Set(":calendardisabled", !isEnabled);
- }
- }
- }
|