/// <summary>
 /// Initializes a new instance of the <see cref="MonthCalendarHitTest"/> class.
 /// </summary>
 /// <param name="date">The date of the hit test.</param>
 /// <param name="type">The result type of the hit test.</param>
 /// <param name="bounds">The bounds of the resulting element.</param>
 public MonthCalendarHitTest(
    DateTime date,
    MonthCalendarHitType type,
    Rectangle bounds)
    : this(date, type, bounds, Rectangle.Empty)
 {
 }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MonthCalendarHitTest"/> class.
 /// </summary>
 /// <param name="date">The date of the hit test.</param>
 /// <param name="type">The result type of the hit test.</param>
 /// <param name="bounds">The bounds of the resulting element.</param>
 public MonthCalendarHitTest(
     DateTime date,
     MonthCalendarHitType type,
     Rectangle bounds)
     : this(date, type, bounds, Rectangle.Empty)
 {
 }
示例#3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MonthCalendarHitTest"/> class.
 /// </summary>
 /// <param name="date">
 /// The date of the hit test.
 /// </param>
 /// <param name="type">
 /// The result type of the hit test.
 /// </param>
 /// <param name="bounds">
 /// The bounds of the resulting element.
 /// </param>
 /// <param name="invalidateBounds">
 /// The bounds to invalidate.
 /// </param>
 public MonthCalendarHitTest(DateTime date, MonthCalendarHitType type, Rectangle bounds, Rectangle invalidateBounds)
 {
     this.Date = date;
     this.Type = type;
     this.Bounds = bounds;
     this._invalidateBounds = invalidateBounds;
 }
示例#4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MonthCalendarHitTest"/> class.
 /// </summary>
 /// <param name="date">The date of the hit test.</param>
 /// <param name="type">The result type of the hit test.</param>
 /// <param name="bounds">The bounds of the resulting element.</param>
 /// <param name="invalidateBounds">The bounds to invalidate.</param>
 public MonthCalendarHitTest(
     DateTime date,
     MonthCalendarHitType type,
     Rectangle bounds,
     Rectangle invalidateBounds)
 {
     this.Date             = date;
     this.Type             = type;
     this.Bounds           = bounds;
     this.invalidateBounds = invalidateBounds;
 }
示例#5
0
      /// <summary>
      /// Initializes a new instance of the <see cref="MonthCalendar"/> class.
      /// </summary>
      public MonthCalendar()
      {
         SetStyle(
               ControlStyles.OptimizedDoubleBuffer
               | ControlStyles.ResizeRedraw
               | ControlStyles.Selectable
               | ControlStyles.AllPaintingInWmPaint
               | ControlStyles.UserPaint
               | ControlStyles.SupportsTransparentBackColor,
               true);

         // initialize menus
         this.InitializeComponent();

         this.extendSelection = false;
         this.showFooter = true;
         this.showWeekHeader = true;
         this.mouseLocation = Point.Empty;
         this.yearSelected = DateTime.MinValue;
         this.monthSelected = DateTime.MinValue;
         this.selectionStart = DateTime.Today;
         this.selectionEnd = DateTime.Today;
         this.currentHitType = MonthCalendarHitType.None;
         this.boldedDates = new List<DateTime>();
         this.boldDatesCollection = new BoldedDatesCollection();
         this.boldDateCategoryCollection = new BoldedDateCategoryCollection(this);
         this.currentMoveBounds = Rectangle.Empty;
         this.mouseMoveFlags = new MonthCalendarMouseMoveFlags();
         this.selectionRanges = new List<SelectionRange>();
         this.daySelectionMode = MonthCalendarSelectionMode.Manual;
         this.nonWorkDays = CalendarDayOfWeek.Saturday | CalendarDayOfWeek.Sunday;
         this.culture = CultureInfo.CurrentUICulture;
         this.cultureCalendar = CultureInfo.CurrentUICulture.DateTimeFormat.Calendar;
         this.eraRanges = GetEraRanges(this.cultureCalendar);
         this.minDate = this.cultureCalendar.MinSupportedDateTime.Date < new DateTime(1900, 1, 1) ? new DateTime(1900, 1, 1) : this.cultureCalendar.MinSupportedDateTime.Date;
         this.maxDate = this.cultureCalendar.MaxSupportedDateTime.Date > new DateTime(9998, 12, 31) ? new DateTime(9998, 12, 31) : this.cultureCalendar.MaxSupportedDateTime.Date;
         this.formatProvider = new MonthCalendarFormatProvider(this.culture, null, this.culture.TextInfo.IsRightToLeft) { MonthCalendar = this };
         this.renderer = new MonthCalendarRenderer(this);
         this.calendarDimensions = new Size(1, 1);
         this.headerFont = new Font("Segoe UI", 9f, FontStyle.Regular);
         this.footerFont = new Font("Arial", 9f, FontStyle.Bold);
         this.dayHeaderFont = new Font("Segoe UI", 8f, FontStyle.Regular);
         this.dayTextAlign = ContentAlignment.MiddleCenter;

         // update year menu
         this.UpdateYearMenu(DateTime.Today.Year);

         // set start date
         this.SetStartDate(new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1));

         this.CalculateSize(true);
      }
示例#6
0
      /// <summary>
      /// Raises the <see cref="System.Windows.Forms.Control.MouseUp"/> event.
      /// </summary>
      /// <param name="e">A <see cref="MouseEventArgs"/> that contains the event data.</param>
      protected override void OnMouseUp(MouseEventArgs e)
      {
         base.OnMouseUp(e);

         // if left mouse button is pressed and selection process was started
         if (e.Button == MouseButtons.Left && this.selectionStarted)
         {
            this.selectionRanges.Add(new SelectionRange(this.SelectionRange.Start, this.SelectionRange.End));

            // reset selection process
            this.selectionStarted = false;

            this.Refresh();

            // raise selected event if necessary
            if (this.backupRange.Start != this.SelectionRange.Start
               || this.backupRange.End != this.SelectionRange.End)
            {
               // raise date 
               this.RaiseDateSelected();
            }
         }

         // reset current hit type
         this.currentHitType = MonthCalendarHitType.None;

         this.Capture = false;
      }
示例#7
0
      /// <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;
                  }
            }
         }
      }