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-in-vb.net.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 dateValue As
String
' acceptOnlyBoldedDates would contain the selected Date
Private acceptOnlyBoldedDates As
Boolean
#End Region


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 Sub SetAnnuallyBoldedDates(ByVal dates As DateTime())Me.monthCalendarDate.AnnuallyBoldedDates = dates
End Sub

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 Sub monthCalendarDate_DateChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DateRangeEventArgs)
If Me.acceptOnlyBoldedDates = False Then
Me
.dateValue = Me.monthCalendarDate.SelectionStart.ToShortDateString()Me.textBoxDate.Text = Me.dateValue
Me.monthCalendarDate.Visible = False
Else
Dim
setDateTime As Boolean = False
Dim
selectedDateTime As DateTime= Me.monthCalendarDate.SelectionStart
For Each dt As DateTime In Me.monthCalendarDate.AnnuallyBoldedDates
If (dt.Date.Day = selectedDateTime.Date.Day) AndAlso (dt.Date.Month = selectedDateTime.Date.Month) Then
Me
.dateValue = Me.monthCalendarDate.SelectionStart.ToShortDateString()

Me
.textBoxDate.Text = Me.dateValue
Me.monthCalendarDate.Visible = False
setDateTime = True
Exit
For
End
If
Next
dt
If (Not setDateTime)
Then
Me
.dateValue = ""
Me.textBoxDate.Text = Me.dateValue
Me.monthCalendarDate.Visible = False
End
If
End
If
End
Sub
' <summary>
' Occurs when the KeyUp Event of the TextBoxDate occurs
' </summary>
' <param name="sender"></param>
' <param name="e"></param>

Private

Sub textBoxDate_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
If e.KeyCode = Keys.Delete
Then
Me
.dateValue = ""
End If
End
Sub
' <summary>
' Occurs on click event of the buttonDate Control''' </summary>
' <param name="sender"></param>
' <param name="e"></param>
Private Sub buttonDate_Click(ByVal sender As Object, ByVal e As System.EventArgs)Me.monthCalendarDate.Visible = True
End
Sub
' <summary>
' Occurs on Calendar Load event
' </summary>
' <param name="sender"></param>
' <param name="e"></param>
Private Sub Calendar_Load(ByVal sender As Object, ByVal e As System.EventArgs)Me.monthCalendarDate.Visible = False
End
Sub
' <summary>
' Occurs on TextBox Leave Event
' </summary>''' <param name="sender"></param>
' <param name="e"></param>
Private Sub textBoxDate_Leave(ByVal sender As Object, ByVal e As System.EventArgs)Try
Dim
dt As DateTime = Convert.ToDateTime(Me.textBoxDate.Text)
Catch ex As Exception
Me.dateValue = ""
Me.textBoxDate.Text = ""
End Try
End
Sub
' <summary>
' public method exposed to set the annuallyboldedDates
' </summary>
' <param name="sender"></param>
' <param name="e"></param>
Public Sub SetAnnuallyBoldedDates(ByVal dates As DateTime())Me.monthCalendarDate.AnnuallyBoldedDates = dates
End
Sub

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:

Me

.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