/// <summary> /// Initializes a new instance of the <see cref="MonthCalendarMonth"/> class. /// </summary> /// <param name="monthCal">The <see cref="MonthCalendar"/> which hosts the <see cref="MonthCalendarMonth"/> instance.</param> /// <param name="date">The date that represents the month and year which is displayed in this instance.</param> public MonthCalendarMonth(MonthCalendar monthCal, DateTime date) { this.MonthCalendar = monthCal; this.Date = date; this.location = new Point(0, 0); MonthCalendarDate dt = new MonthCalendarDate(monthCal.CultureCalendar, date).FirstOfMonth.GetFirstDayInWeek(monthCal.FormatProvider); List<MonthCalendarDay> dayList = new List<MonthCalendarDay>(); List<MonthCalendarWeek> weekList = new List<MonthCalendarWeek>(); int dayAdjust = 0; while (dt.AddDays(dayAdjust).DayOfWeek != monthCal.FormatProvider.FirstDayOfWeek) { dayAdjust++; } int d = dayAdjust != 0 ? 8 - dayAdjust : 0; for (int i = dayAdjust; i < 42 + dayAdjust; i++, dt = dt.AddDays(1)) { MonthCalendarDay day = new MonthCalendarDay(this, dt.Date); dayList.Add(day); if (day.Visible) { if (this.firstVisibleDate == DateTime.MinValue) { this.firstVisibleDate = dt.Date; } if (!day.TrailingDate) { this.lastVisibleDate = dt.Date; } } if (i == dayAdjust || ((i - d) % 7) == 0) { DateTime weekEnd = dt.GetEndDateOfWeek(monthCal.FormatProvider).Date; int weekNumEnd = DateMethods.GetWeekOfYear(monthCal.Culture, monthCal.CultureCalendar, weekEnd); weekList.Add(new MonthCalendarWeek(this, weekNumEnd, dt.Date, weekEnd)); } if (dt.Date == monthCal.CultureCalendar.MaxSupportedDateTime.Date) { break; } } this.Days = dayList.ToArray(); this.Weeks = weekList.ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="MonthCalendarMonth"/> class. /// </summary> /// <param name="monthCal">The <see cref="MonthCalendar"/> which hosts the <see cref="MonthCalendarMonth"/> instance.</param> /// <param name="date">The date that represents the month and year which is displayed in this instance.</param> public MonthCalendarMonth(MonthCalendar monthCal, DateTime date) { this.MonthCalendar = monthCal; this.Date = date; this.location = new Point(0, 0); MonthCalendarDate dt = new MonthCalendarDate(monthCal.CultureCalendar, date).FirstOfMonth.GetFirstDayInWeek(monthCal.FormatProvider); List <MonthCalendarDay> dayList = new List <MonthCalendarDay>(); List <MonthCalendarWeek> weekList = new List <MonthCalendarWeek>(); int dayAdjust = 0; while (dt.AddDays(dayAdjust).DayOfWeek != monthCal.FormatProvider.FirstDayOfWeek) { dayAdjust++; } int d = dayAdjust != 0 ? 8 - dayAdjust : 0; for (int i = dayAdjust; i < 42 + dayAdjust; i++, dt = dt.AddDays(1)) { MonthCalendarDay day = new MonthCalendarDay(this, dt.Date); dayList.Add(day); if (day.Visible) { if (this.firstVisibleDate == DateTime.MinValue) { this.firstVisibleDate = dt.Date; } if (!day.TrailingDate) { this.lastVisibleDate = dt.Date; } } if (i == dayAdjust || ((i - d) % 7) == 0) { DateTime weekEnd = dt.GetEndDateOfWeek(monthCal.FormatProvider).Date; int weekNumEnd = DateMethods.GetWeekOfYear(monthCal.Culture, monthCal.CultureCalendar, weekEnd); weekList.Add(new MonthCalendarWeek(this, weekNumEnd, dt.Date, weekEnd)); } if (dt.Date == monthCal.CultureCalendar.MaxSupportedDateTime.Date) { break; } } this.Days = dayList.ToArray(); this.Weeks = weekList.ToArray(); }
/// <summary> /// Gets the first day in the week. /// </summary> /// <param name="provider">The format provider.</param> /// <returns>The first day in the week specified by this instance.</returns> public MonthCalendarDate GetFirstDayInWeek(ICustomFormatProvider provider) { DayOfWeek firstDayOfWeek = provider.FirstDayOfWeek; MonthCalendarDate dt = (MonthCalendarDate)this.Clone(); while (dt.DayOfWeek != firstDayOfWeek && dt.Date > this.calendar.MinSupportedDateTime) { dt = dt.AddDays(-1); } return(dt); }
/// <summary> /// Sets the selection range for the specified <see cref="MonthCalendarSelectionMode"/>. /// </summary> /// <param name="selMode">The <see cref="MonthCalendarSelectionMode"/> value to set the selection range for.</param> private void SetSelectionRange(MonthCalendarSelectionMode selMode) { switch (selMode) { case MonthCalendarSelectionMode.Day: { this.selectionEnd = this.selectionStart; break; } case MonthCalendarSelectionMode.WorkWeek: case MonthCalendarSelectionMode.FullWeek: { MonthCalendarDate dt = new MonthCalendarDate(this.CultureCalendar, this.selectionStart).GetFirstDayInWeek( this.formatProvider); this.selectionStart = dt.Date; this.selectionEnd = dt.AddDays(6).Date; break; } case MonthCalendarSelectionMode.Month: { MonthCalendarDate dt = new MonthCalendarDate(this.CultureCalendar, this.selectionStart).FirstOfMonth; this.selectionStart = dt.Date; this.selectionEnd = dt.AddMonths(1).AddDays(-1).Date; break; } } }
/// <summary> /// Sets the start date. /// </summary> /// <param name="start">The start date.</param> /// <returns>true if <paramref name="start"/> is valid; false otherwise.</returns> private bool SetStartDate(DateTime start) { if (start < DateTime.MinValue.Date || start > DateTime.MaxValue.Date) { return false; } DayOfWeek firstDayOfWeek = this.formatProvider.FirstDayOfWeek; MonthCalendarDate dt = new MonthCalendarDate(this.CultureCalendar, this.maxDate); if (start > this.maxDate) { start = dt.AddMonths(1 - this.months.Length).FirstOfMonth.Date; } if (start < this.minDate) { start = this.minDate; } dt = new MonthCalendarDate(this.CultureCalendar, start); int length = this.months != null ? this.months.Length - 1 : 0; while (dt.Date > this.minDate && dt.Day != 1) { dt = dt.AddDays(-1); } MonthCalendarDate endDate = dt.AddMonths(length); MonthCalendarDate endDateDay = endDate.AddDays(endDate.DaysInMonth - 1 - (endDate.Day - 1)); if (endDate.Date >= this.maxDate || endDateDay.Date >= this.maxDate) { dt = new MonthCalendarDate(this.CultureCalendar, this.maxDate).AddMonths(-length).FirstOfMonth; } this.viewStart = dt.Date; while (dt.Date > this.CultureCalendar.MinSupportedDateTime.Date && dt.DayOfWeek != firstDayOfWeek) { dt = dt.AddDays(-1); } this.realStart = dt.Date; return true; }
/// <summary> /// Raises the <see cref="System.Windows.Forms.Control.MouseDown"/> event. /// </summary> /// <param name="e">A <see cref="MouseEventArgs"/> that contains the event data.</param> protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); this.Focus(); this.Capture = true; // reset the selection range where selection started this.selectionStartRange = null; if (e.Button == MouseButtons.Left) { // perform hit test MonthCalendarHitTest hit = this.HitTest(e.Location); // set current bounds this.currentMoveBounds = hit.Bounds; // set current hit type this.currentHitType = hit.Type; switch (hit.Type) { case MonthCalendarHitType.Day: { // save old selection range SelectionRange oldRange = this.SelectionRange; if (!this.extendSelection || this.daySelectionMode != MonthCalendarSelectionMode.Manual) { // clear all selection ranges this.selectionRanges.Clear(); } switch (this.daySelectionMode) { case MonthCalendarSelectionMode.Day: { this.OnDateClicked(new DateEventArgs(hit.Date)); // only single days are selectable if (this.selectionStart != hit.Date) { this.SelectionStart = hit.Date; this.RaiseDateSelected(); } break; } case MonthCalendarSelectionMode.WorkWeek: { // only single work week is selectable // get first day of week DateTime firstDay = new MonthCalendarDate(this.CultureCalendar, hit.Date).GetFirstDayInWeek(this.formatProvider).Date; // get work days List<DayOfWeek> workDays = DateMethods.GetWorkDays(this.nonWorkDays); // reset selection start and end this.selectionEnd = DateTime.MinValue; this.selectionStart = DateTime.MinValue; // current range SelectionRange currentRange = null; // build selection ranges for work days for (int i = 0; i < 7; i++) { DateTime toAdd = firstDay.AddDays(i); if (workDays.Contains(toAdd.DayOfWeek)) { if (currentRange == null) { currentRange = new SelectionRange(DateTime.MinValue, DateTime.MinValue); } if (currentRange.Start == DateTime.MinValue) { currentRange.Start = toAdd; } else { currentRange.End = toAdd; } } else if (currentRange != null) { this.selectionRanges.Add(currentRange); currentRange = null; } } if (this.selectionRanges.Count >= 1) { // set first selection range this.SelectionRange = this.selectionRanges[0]; this.selectionRanges.RemoveAt(0); // if selection range changed, raise event if (this.SelectionRange != oldRange) { this.RaiseDateSelected(); } } else { this.Refresh(); } break; } case MonthCalendarSelectionMode.FullWeek: { // only a full week is selectable // get selection start and end MonthCalendarDate dt = new MonthCalendarDate(this.CultureCalendar, hit.Date).GetFirstDayInWeek( this.formatProvider); this.selectionStart = dt.Date; this.selectionEnd = dt.GetEndDateOfWeek(this.formatProvider).Date; // if range changed, raise event if (this.SelectionRange != oldRange) { this.RaiseDateSelected(); this.Refresh(); } break; } case MonthCalendarSelectionMode.Month: { // only a full month is selectable MonthCalendarDate dt = new MonthCalendarDate(this.CultureCalendar, hit.Date).FirstOfMonth; // get selection start and end this.selectionStart = dt.Date; this.selectionEnd = dt.AddMonths(1).AddDays(-1).Date; // if range changed, raise event if (this.SelectionRange != oldRange) { this.RaiseDateSelected(); this.Refresh(); } break; } case MonthCalendarSelectionMode.Manual: { if (this.extendSelection) { var range = this.selectionRanges.Find(r => hit.Date >= r.Start && hit.Date <= r.End); if (range != null) { this.selectionRanges.Remove(range); } } // manual mode - selection ends when user is releasing the left mouse button this.selectionStarted = true; this.backupRange = this.SelectionRange; this.selectionEnd = DateTime.MinValue; this.SelectionStart = hit.Date; break; } } break; } case MonthCalendarHitType.Week: { this.selectionRanges.Clear(); if (this.maxSelectionCount > 6 || this.maxSelectionCount == 0) { this.backupRange = this.SelectionRange; this.selectionStarted = true; this.selectionEnd = new MonthCalendarDate(this.CultureCalendar, hit.Date).GetEndDateOfWeek(this.formatProvider).Date; this.SelectionStart = hit.Date; this.selectionStartRange = this.SelectionRange; } break; } case MonthCalendarHitType.MonthName: { this.monthSelected = hit.Date; this.mouseMoveFlags.HeaderDate = hit.Date; this.Invalidate(hit.InvalidateBounds); this.Update(); this.monthMenu.Tag = hit.Date; this.UpdateMonthMenu(this.CultureCalendar.GetYear(hit.Date)); this.showingMenu = true; // show month menu this.monthMenu.Show(this, hit.Bounds.Right, e.Location.Y); break; } case MonthCalendarHitType.MonthYear: { this.yearSelected = hit.Date; this.mouseMoveFlags.HeaderDate = hit.Date; this.Invalidate(hit.InvalidateBounds); this.Update(); this.UpdateYearMenu(this.CultureCalendar.GetYear(hit.Date)); this.yearMenu.Tag = hit.Date; this.showingMenu = true; // show year menu this.yearMenu.Show(this, hit.Bounds.Right, e.Location.Y); break; } case MonthCalendarHitType.Arrow: { // an arrow was pressed // set new start date if (this.SetStartDate(hit.Date)) { // update months this.UpdateMonths(); // raise event this.RaiseDateChanged(); this.mouseMoveFlags.HeaderDate = this.leftArrowRect.Contains(e.Location) ? this.months[0].Date : this.months[this.calendarDimensions.Width - 1].Date; this.Refresh(); } break; } case MonthCalendarHitType.Footer: { // footer was pressed this.selectionRanges.Clear(); bool raiseDateChanged = false; SelectionRange range = this.SelectionRange; // determine if date changed event has to be raised if (DateTime.Today < this.months[0].FirstVisibleDate || DateTime.Today > this.lastVisibleDate) { // set new start date if (this.SetStartDate(DateTime.Today)) { // update months this.UpdateMonths(); raiseDateChanged = true; } else { break; } } // set new selection start and end values this.selectionStart = DateTime.Today; this.selectionEnd = DateTime.Today; this.SetSelectionRange(this.daySelectionMode); this.OnDateClicked(new DateEventArgs(DateTime.Today)); // raise events if necessary if (range != this.SelectionRange) { this.RaiseDateSelected(); } if (raiseDateChanged) { this.RaiseDateChanged(); } this.Refresh(); break; } case MonthCalendarHitType.Header: { // header was pressed this.Invalidate(hit.Bounds); this.Update(); break; } } } }
/// <summary> /// Processes a dialog key. /// </summary> /// <param name="keyData">One of the <see cref="Keys"/> value that represents the key to process.</param> /// <returns>true if the key was processed by the control; otherwise, false.</returns> protected override bool ProcessDialogKey(Keys keyData) { if (this.daySelectionMode != MonthCalendarSelectionMode.Day) { return base.ProcessDialogKey(keyData); } MonthCalendarDate dt = new MonthCalendarDate(this.cultureCalendar, this.selectionStart); bool retValue = false; if (keyData == Keys.Left) { this.selectionStart = dt.AddDays(-1).Date; retValue = true; } else if (keyData == Keys.Right) { this.selectionStart = dt.AddDays(1).Date; retValue = true; } else if (keyData == Keys.Up) { this.selectionStart = dt.AddDays(-7).Date; retValue = true; } else if (keyData == Keys.Down) { this.selectionStart = dt.AddDays(7).Date; retValue = true; } if (retValue) { if (this.selectionStart < this.minDate) { this.selectionStart = this.minDate; } else if (this.selectionStart > this.maxDate) { this.selectionStart = this.maxDate; } this.SetSelectionRange(this.daySelectionMode); this.EnsureSeletedDateIsVisible(); this.RaiseInternalDateSelected(); this.Invalidate(); return true; } return base.ProcessDialogKey(keyData); }