|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe same old story: I needed a date-time picker that could display a blank value, and I did not want to have to train my users that a grayed-out date with no check in the box really means there is no date. After looking through the many controls here at CodeProject, I got a bit dismayed. I made my own stab at it using VB and Visual Studio 2008, and I got something I liked without having to do a lot of work. Using the codeThe base control itself is pretty straightforward: a The code defining the pop-up is embedded in the control as a private class. Writing it was very straightforward: I created a regular Protected Class Calendar
Inherits System.Windows.Forms.Form
Private MyPicker As NullableDateTimePicker
Private WithEvents Label1 As Label
Private WithEvents Label2 As Label
Private WithEvents MonthCalendar1 As MonthCalendar
Public Sub New(ByRef Picker As NullableDateTimePicker)
MyPicker = Picker
Me.MonthCalendar1 = New MonthCalendar
Me.Label1 = New Label
Me.Label2 = New Label
Me.SuspendLayout()
'
'MonthCalendar1
'
Me.MonthCalendar1.Location = New Point(0, 0)
Me.MonthCalendar1.Margin = New Padding(0)
Me.MonthCalendar1.MaxSelectionCount = 1
Me.MonthCalendar1.Name = "MonthCalendar1"
Me.MonthCalendar1.ShowTodayCircle = False
Me.MonthCalendar1.TabIndex = 0
'
'Label1
'
Me.Label1.Font = New Font("Microsoft Sans Serif", 8.25!, _
FontStyle.Underline, GraphicsUnit.Point, CType(0, Byte))
Me.Label1.ForeColor = SystemColors.HotTrack
Me.Label1.Location = New Point(2, 163)
Me.Label1.Name = "Label1"
Me.Label1.Size = New Size(55, 13)
Me.Label1.TabIndex = 1
Me.Label1.Text = "Clear date"
'
'Label2
'
Me.label2.AutoSize = True
Me.label2.Font = New Font("Microsoft Sans Serif", 8.25!, _
FontStyle.Underline, GraphicsUnit.Point, CType(0, Byte))
Me.label2.ForeColor = System.Drawing.SystemColors.HotTrack
Me.label2.Location = New System.Drawing.Point(192, 163)
Me.label2.Name = "Label2"
Me.label2.Size = New System.Drawing.Size(33, 13)
Me.label2.TabIndex = 2
Me.label2.Text = "Close"
'
'CalendarPopup
'
Me.AutoScaleDimensions = New SizeF(6.0!, 13.0!)
Me.AutoScaleMode = AutoScaleMode.Font
Me.ClientSize = New Size(228, 184)
Me.ControlBox = False
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.MonthCalendar1)
Me.FormBorderStyle = FormBorderStyle.FixedToolWindow
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "CalendarPopup"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.StartPosition = FormStartPosition.Manual
Me.ResumeLayout(False)
End Sub
Public Property SelectedDate() As Date?
Get
If Information.IsDate(MonthCalendar1.SelectionStart) Then
Return MonthCalendar1.SelectionStart
Else
Return Nothing
End If
End Get
Set(ByVal value As Date?)
If Information.IsDate(value) Then
MonthCalendar1.SetDate(Convert.ToDateTime(value))
Else
MonthCalendar1.SetDate(DateTime.Now)
End If
End Set
End Property
Private Sub Label1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Label1.Click
'Clear
MyPicker.Value = Nothing
Me.Close()
End Sub
Private Sub Label2_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Label2.Click
'Close
Me.Close()
End Sub
Private Sub MonthCalendar1_DateSelected(ByVal sender As Object, _
ByVal e As DateRangeEventArgs) _
Handles MonthCalendar1.DateSelected
MyPicker.Value = e.Start
Me.Close()
End Sub
End Class
The Private Sub Button1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles Button1.MouseDown
If Cal Is Nothing Then Cal = New Calendar(Me)
If Cal.Visible Then Exit Sub
If Information.IsDate(MaskedTextBox1.Text) Then
Cal.SelectedDate = Convert.ToDateTime(MaskedTextBox1.Text)
Else
Cal.SelectedDate = Nothing
End If
Cal.Location = Button1.PointToScreen(New Point(0, 19))
Cal.ShowDialog()
End Sub
Getting the date out of the control is pretty straightforward. I have implemented Public ReadOnly Property HasDate() As Boolean
Get
Return Information.IsDate(MaskedTextBox1)
End Get
End Property
Public Overrides Property Text() As String
Get
Return MaskedTextBox1.Text
End Get
Set(ByVal value As String)
MaskedTextBox1.Text = value
End Set
End Property
Public Property Value() As Date?
Get
If Me.HasDate Then
Return Convert.ToDateTime(MaskedTextBox1.Text)
Else
Return Nothing
End If
End Get
Set(ByVal value As Date?)
If Information.IsDate(value) Then
MaskedTextBox1.Text = _
Convert.ToDateTime(value).ToString("MM/dd/yyyy")
Else
MaskedTextBox1.Text = ""
End If
End Set
End Property
Room for improvementThis control is pretty basic, but it does what I need: allows the user to easily select a date, to manually enter a date, and to represent the absence of a date. Making it data-bound should be pretty easy. Properties to change the appearance of the calendar pop-up would also be handy. Points of interestNote the use of As noted above, Visual Basic 2008 has added a shorthand notation for History
|
||||||||||||||||||||||