Introduction

Visual Studio 2003 ships in with DateTimePicker Control for selecting Date. But the DateTimePicker inherently has it own limitations. It does not allow the following:

  1. To edit Dates; it allows only selection of Dates.
  2. Null Dates
  3. Set a collection of Dates to be bolded.

The Custom Calendar Control described in this paper overcomes the above limitations of the DateTimePicker by enhancing the capabilities of the existing MonthCalendar Control provided by Visual Studio .Net.

The Solution

Visual Studio 2003 ships in with a Month Calendar Control which allows Dates to be bolded. We can enhance the Month Calendar by coupling it with a TextBox and a Button Control and overcome the limitations of the DateTimePicker Control.

Implementation

For enhancing the capabilities of the DateTimePicker Control, the following steps are required to be implemented:

Step 1:

Create a custom project of type Windows Control Library. Within the library add a new file of type Custom Control. We are in effect creating a new control altogether using the Textbox, Button and MonthCalendar Control

Step 2:

To the Custom Control add a TextBox and a Button Control name the textBoxDate and buttonDate respectively. Name the new Control as Calendar Control.

The general look and feel of the custom Calendar is as follows:

Calendar.gif
Step 3:

The functionality to be implemented requires controlling the visibility of the MonthCalendar Control depending on the clicking of the buttonDate Control. Once the Date is selected, the Month Calendar control should become invisible by default.

Also to support nullable dates, the textbox controls text is used to support blank values.

Declare the following variables in the Custom Control:

#region Variables
// dateValue would contain the selected Date
private string
dateValue ;
// acceptOnlyBoldedDates would contain the selected Date
private bool
acceptOnlyBoldedDates;
#endregion

The dateValue string would contain the selectedDate in string format, which allows Null Dates as well.

The acceptOnlyBoldedDates is a property that is exposed to the user of the Control. Setting this property to true would enable the validation check that the selected Date falls in one of the bolded Dates already set by the user programmatically.

If the acceptOnlyBoldedDates is set to false, any valid date that the user enters would be selected. When set to true, the date entered would necessarily should be one previously set bolded dates.

Step 4:

For setting the bolded Dates, the following function is exposed. The user can programmatically use the SetAnnuallyBoldedDates to set a list of Bolded Dates.

/// <summary>
///
public method exposed to set the annuallyboldedDates
///
</summary>
///
<param name="sender"></param>
/// <param name="e"></param>

public void
SetAnnuallyBoldedDates(DateTime [] dates)
{
this.monthCalendarDate.AnnuallyBoldedDates = dates ;
}

Step 5:

Declare the following event handlers in the Custom Calendar Class:

/// <summary>
///
Occurs when the Date of the Calendar changes
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private void monthCalendarDate_DateChanged(object
sender, System.Windows.Forms.DateRangeEventArgs e)
{
if ( this.acceptOnlyBoldedDates == false
)
{
this.dateValue = this
.monthCalendarDate.SelectionStart.ToShortDateString();
this.textBoxDate.Text = this
.dateValue ;
this.monthCalendarDate.Visible = false
;
}
else
{
bool setDateTime = false
;
DateTime selectedDateTime=
this
.monthCalendarDate.SelectionStart;
foreach(DateTime dt in this
.monthCalendarDate.AnnuallyBoldedDates)
{
if
( ( dt.Date.Day == selectedDateTime.Date.Day ) &&( dt.Date.Month == selectedDateTime.Date.Month ))
{
this.dateValue = this
.monthCalendarDate.SelectionStart.ToShortDateString();
this.textBoxDate.Text = this
.dateValue ;
this.monthCalendarDate.Visible = false
;
setDateTime =
true
;
break
;
}
}
if
(!setDateTime)
{
this
.dateValue = "";
this.textBoxDate.Text = this
.dateValue ;
this.monthCalendarDate.Visible = false
;
}
}
}
///
<summary>
///
Occurs when the KeyUp Event of the TextBoxDate occurs
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private void textBoxDate_KeyUp(object
sender,
System.Windows.Forms.KeyEventArgs e)
{
if
(e.KeyCode == Keys.Delete)
{
this
.dateValue = "";
}
}
///
<summary>
///
Occurs on click event of the buttonDate Control
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private void buttonDate_Click(object
sender, System.EventArgs e)
{
this.monthCalendarDate.Visible = true
;
}
///
<summary>
///
Occurs on Calendar Load event
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private void Calendar_Load(object
sender, System.EventArgs e)
{
this.monthCalendarDate.Visible = false
;
}
///
<summary>
///
Occurs on TextBox Leave Event
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private void textBoxDate_Leave(object
sender, System.EventArgs e)
{
try

{
DateTime dt = Convert.ToDateTime(
this
.textBoxDate.Text);
}
catch
(Exception ex)
{
this
.dateValue = "";
this
.textBoxDate.Text = "";
}
}
///
<summary>
///
public method exposed to set the annuallyboldedDates
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
public void
SetAnnuallyBoldedDates(DateTime [] dates)
{
this
.monthCalendarDate.AnnuallyBoldedDates = dates ;
}

Step 6:

Add to Solution a Test Project. Add a reference to the Calendar Library Project in the References section. Rename the form appropriately and drag and drop the Control from the Toolbox on the Form. On the load event of the Form set the bolded dates as follows:

this.calendar.SetAnnuallyBoldedDates(
new
System.DateTime[] {
new
System.DateTime(2005, 4, 20, 0, 0, 0, 0),
new
System.DateTime(2005, 4, 28, 0, 0, 0, 0),
new
System.DateTime(2005, 5, 5, 0, 0, 0, 0),
new
System.DateTime(2005, 7, 4, 0, 0, 0, 0),
new
System.DateTime(2005, 12, 15, 0, 0, 0, 0),
new System.DateTime(2005, 12, 18, 0, 0, 0, 0)});

In the Design View set the acceptOnlyBoldedDates property of the Calendar Control to true.

Step 7:

Set the Test Project as the startup project and execute the project. Since the acceptOnlyBoldedDates property was set to true, the control accepts only Dates that are in the Bolded Date Collection.

Conclusion

Thus we have successfully created a Control that has all the capabilities of the existing DateTimePicker enhanced along with additional capabilities imparted from that of MonthCalendar Control.

Next Recommended Readings