namespace System.Windows.Forms { public class MonthCalendar : Control { protected new CustomControls.Calendar control { get; } public DateTime MinDate { get => control.DisplayDateStart ?? DateTime.MinValue; set => control.DisplayDateStart = value; } public DateTime MaxDate { get => control.DisplayDateEnd ?? DateTime.MaxValue; set => control.DisplayDateEnd = value; } private DateTime selectionStart = DateTime.MinValue; public DateTime SelectionStart { get => selectionStart; set { selectionStart = value; UpdateSelectionRange(); } } private DateTime selectionEnd; public DateTime SelectionEnd { get => selectionEnd; set { selectionEnd = value; UpdateSelectionRange(); } } public SelectionRange SelectionRange { get => GetSelectedRange(); set { SelectionStart = value.Start; SelectionEnd = value.End; } } public int MaxSelectionCount { get; set; } // TODO? public Drawing.Size CalendarDimensions { get; set; } // TODO? public Day FirstDayOfWeek { get { return control.ReadLocalValue(System.Windows.Controls.Calendar.FirstDayOfWeekProperty) == DependencyProperty.UnsetValue ? Day.Default : Helper.GetDay(control.FirstDayOfWeek); } set { if (value == Day.Default) control.ClearValue(System.Windows.Controls.Calendar.FirstDayOfWeekProperty); else control.FirstDayOfWeek = Helper.GetDayOfWeek(value); } } public bool ShowToday { get => control.IsTodayHighlighted; set => control.IsTodayHighlighted = value; } public bool ShowTodayCircle { get; set; } // nope public bool ShowWeekNumbers { get; set; } // nope public DateTime TodayDate { get; set; } // nope public DateTime[] AnnuallyBoldedDates { get => control.AnnualDates; set => control.AnnualDates = value; } public DateTime[] MonthlyBoldedDates { get => control.MonthDates; set => control.MonthDates = value; } public DateTime[] BoldedDates { get => control.Dates; set => control.Dates = value; } public event DateRangeEventHandler DateChanged; public event DateRangeEventHandler DateSelected; private void UpdateSelectionRange() { control.SelectedDates.Clear(); var start = SelectionStart; var end = SelectionEnd; if (start >= MinDate && start <= MaxDate && end >= MinDate && end <= MaxDate && start <= end) { control.SelectedDates.AddRange(SelectionStart, SelectionEnd); } } private SelectionRange GetSelectedRange() { var start = DateTime.MaxValue; var end = DateTime.MinValue; foreach (var date in control.SelectedDates) { if (date > end) end = date; if (date < start) start = date; } return new SelectionRange(start, end.Add(new TimeSpan(23, 59, 59))); } protected virtual void OnDateSelected(DateRangeEventArgs e) { DateChanged?.Invoke(this, e); DateSelected?.Invoke(this, e); } public MonthCalendar() { control = new(); SetControl(control); AutoSize = true; control.SelectionMode = Windows.Controls.CalendarSelectionMode.SingleRange; control.SelectedDatesChanged += (s, e) => { var range = GetSelectedRange(); selectionStart = range.Start; selectionEnd = range.End; OnDateSelected(new DateRangeEventArgs(selectionStart, selectionEnd)); }; } } }