Click here to Skip to main content
15,881,559 members
Articles / Multimedia / GDI+
Article

Customizable MonthCalendar Type Control: Part 1

Rate me:
Please Sign up or sign in to vote.
4.21/5 (20 votes)
8 Nov 20054 min read 183.3K   13.8K   63   19
A truly customizable MonthCalendar type control.

Sample Image

Introduction

As part of a team creating a CRM software package, I am in charge of the user interface portion of the project. A requisite part of all CRM software is an appointment calendar. I initially chose to use the MonthCalendar control to allow the user to select the date of the appointment. After they create the appointment, I add the new date to the BoldedDates array of the MonthCalendar control to designate an appointment on that date. I was frustrated with the lack of customization available to the MonthCalendar control with regards to appearance. The first meeting with our marketing department (the primary users) yielded requests to make the bolded dates a different color and a more complete month view showing an abbreviation of the appointments for each day. The month view would also need to be printed.

I decided to create my own MonthCalendar type user control that could be used to select a date and display a larger size of the entire month with appointment abbreviations. This is my first Windows control in .NET, I have seven years Windows experience in VB5 and VB6 but I have mainly spent the last 2 years using C# in ASP.NET applications creating online charts using GDI+.

I broke the development up into two parts.

Part 1. – Create my own MonthCalendar type control with the same basic functionality as the .NET MonthCalendar along with the ability to customize all aspects of visual appearance.

Part 2. – Implement the full month view with appointment abbreviations and print functionality.

This article only covers part 1.

Background

The control consists of two Buttons, one Label, and one PictureBox. The Buttons are used to move to the next or previous month. The Label displays the month and year while the PictureBox displays the actual calendar. The calendar is drawn in the Paint event of the PictureBox. The control exposes one additional event, SelectedDateChanged.

The following properties may be changed:

  • Active month background color.
  • Inactive month background color.
  • Header background color.
  • Selected date background color.
  • Selected date font color.
  • Bolded date font color.
  • Grid color.
  • Control background color.
  • Font used for bolded dates.
  • Font used for not bolded dates.

The following properties may be toggled on or off:

  • Display previous and next buttons.
  • Draw the grid.
  • Display month name in active month.
  • Abbreviate day name in header.
  • Display weekend days darker.

The test application demonstrates changing a few of the properties and displays the SelectedDate as the title of the form.

Using the code

The entire structure of the code is based on a 7 x 6 grid I use to display the calendar. A 7 x 6 array of integer arrays hold data about each day represented in the grid, one array for the day number and one for the month number. These values determine how each cell of the grid should be drawn. The PictureBox is divided into an array of rectangles that will be used in the Paint event.

The control may be used anywhere a standard MonthCalendar control would be used and it accepts an array of dates to be bolded. It may be sized to fit the space available.

The function that fills the arrays with the appropriate date data was the most interesting part of this phase. See FillDates() in the source code.

Points of Interest

The control has the ability to display the weekend days slightly darker than the rest of the days of the month. To accomplish this, I create a new color based on the one chosen, and use that color for the brush. In this case, each of the RGB attributes are 80% of the original.

C#
brushActive = new SolidBrush(p_ActiveMonthColor);
ActiveDarker = Color.FromArgb((int)(p_ActiveMonthColor.R*0.8), 
               (int)(p_ActiveMonthColor.G*0.8), 
               (int)(p_ActiveMonthColor.B*0.8));
brushActiveDarker = new SolidBrush(ActiveDarker);

The control exposes one additional event, SelectedDateChanged. This event is fired when the selected date is changed. To do this, I create a class to hold event data. This class must be derived from EventArgs.

C#
using System;

namespace MPK_Calendar
{
    /// <summary>
    /// Event argument class.
    /// </summary>
    public class SelectedDateChangedEventArgs:EventArgs
    {
        private DateTime pSelectedDate;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dateSelected">Date </param>
        public SelectedDateChangedEventArgs(DateTime dateSelected)
        {
            pSelectedDate = dateSelected;
        }

        /// <summary>
        /// The selected date.
        /// </summary>
        public DateTime SelectedDate
        {
            get
            {
                return pSelectedDate;
            }
        }

    }
}

Declare the delegate of the event:

C#
public delegate void SelectedDateChangedEventHandler(object sender, 
                                     SelectedDateChangedEventArgs e);

Provide a public event member:

C#
#region Custom events
/// <summary>
/// Event handler definition
/// </summary>
public event SelectedDateChangedEventHandler SelectedDateChanged;

Create a protected function that raises the event:

C#
protected virtual void 
    OnSelectedDateChanged(SelectedDateChangedEventArgs eventArgs)
{
    if(SelectedDateChanged!=null)
    {
        SelectedDateChanged(this,eventArgs);
    }
}
#endregion Custom events

Finally consume the event in the form of the demo application:

C#
private void mpK_Calendar1_SelectedDateChanged_1(object sender, 
                  MPK_Calendar.SelectedDateChangedEventArgs e)
{
    this.Text = e.SelectedDate.ToShortDateString();
}

Everyone knows that public properties can be edited in the properties editor. The two lines above the property definition allowed me to specify a category and a description for use in the property editor:

C#
[Description("Grid color.")]
[Category("MPK_Calendar")]
public Color GridColor
{
    get
    {
        return p_GridColor;
    }
    set
    {
        pGridColor=value;
        this.picMPK_Cal.Invalidate();
    }
}

History

  • November 8, 2005 - Fixed a bug that occurs when the month is changed. I also changed the way the date information is stored.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I've been developing software since 1995, using VB5, VB6, ASP, Javascript and most recently C# for ASP.NET and Windows. Current interests include embedded systems for robotics with the BASIC Stamp microcontroller from Parallax and the Brainstem module from Acroname.

Comments and Discussions

 
Questionstart the week with monday Pin
Member 155972266-Jul-23 4:02
Member 155972266-Jul-23 4:02 
QuestionSet colors for individuals days? Pin
Winnetou512-Jun-21 9:55
Winnetou512-Jun-21 9:55 
Questionshow more than 1 month Pin
gonzaloleon30-Oct-15 5:25
gonzaloleon30-Oct-15 5:25 
QuestionHow to display database stored event dates in this calendar ? Pin
Murulimadhav117-Jan-15 20:25
Murulimadhav117-Jan-15 20:25 
GeneralMy vote of 2 Pin
Member 982450831-Mar-13 6:11
Member 982450831-Mar-13 6:11 
QuestionFillDates() Pin
Hagitar2-Jan-13 23:00
Hagitar2-Jan-13 23:00 
QuestionWow. I love it, but it lacks one important feature. Pin
Member 840402029-Nov-12 5:05
Member 840402029-Nov-12 5:05 
GeneralMy vote of 3 Pin
TheCrazyTim13-Nov-12 17:47
TheCrazyTim13-Nov-12 17:47 
GeneralSelectionStart method Pin
leszex14910-Dec-09 7:03
leszex14910-Dec-09 7:03 
GeneralIt doesn't work to change to font clor for bolded day Pin
Tanasescu13-Nov-08 6:17
Tanasescu13-Nov-08 6:17 
QuestionHow about an event for NextMonthChange and PrevMonthChange Pin
mlee1steph18-Sep-07 8:30
mlee1steph18-Sep-07 8:30 
Generalim not able to load the project Pin
Mrhoney17-Apr-06 22:34
Mrhoney17-Apr-06 22:34 
QuestionUse of code Pin
stuart277724-Mar-06 10:34
stuart277724-Mar-06 10:34 
GeneralVery interesting, but ... Pin
Tom Janssens9-Nov-05 0:37
Tom Janssens9-Nov-05 0:37 
GeneralRe: Very interesting, but ... Pin
Member 840402029-Nov-12 5:22
Member 840402029-Nov-12 5:22 
QuestionI think it is a strange changing there Pin
MyHolyCow6-Sep-05 9:07
MyHolyCow6-Sep-05 9:07 
AnswerRe: I think it is a strange changing there Pin
chris mook7-Sep-05 3:09
chris mook7-Sep-05 3:09 
GeneralRe: I think it is a strange changing there Pin
Michael Krisky26-Oct-05 9:03
Michael Krisky26-Oct-05 9:03 
GeneralRe: I think it is a strange changing there Pin
antonydenyer8-Nov-05 5:02
antonydenyer8-Nov-05 5:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.