Reputation: 11273
This question is relating to a specific functionality that a client has requested for an application I am designing. Basically, the client wants the DateTimePicker to prompt a question after the date was selected.
This sounds simple, however, I am having difficulties accomplishing this simple task.
So basically, I am trying to think of the best way to prompt a user AFTER they select a date from a dateTimePicker control.
I have no issues with building a custom control either. I have started making one since I also needed to allow NULL values.
Upvotes: 1
Views: 1859
Reputation: 11273
I ended up coding a custom control to handle this the right way. I created a textbox with a button, and added a MonthCalendar control as well.
The textbox+button opens the MonthCalendar control. The only way to choose the datetime now is via the MonthCalendar. You cannot select from the Textbox. I also created a custom event that fires when the date is selected. It works perfectly. Code below:
Public Class CustomDatePicker
'Variables
Friend WithEvents cal As MonthCalendar
Private _isCalendarVisible As Boolean = False
Private _currentSelectedDate As DateTime = Nothing
'Events
Public Event OnDateTimeSet(ByVal sender As Object, ByVal dateValue As DateTime)
Public Event OnDateCleared(ByVal sender As Object)
'Constructor
Public Sub New()
InitializeComponent()
End Sub
'Onload
Private Sub CustomDatePicker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Initially setup calendar
cal = New MonthCalendar
cal.Name = "Calendar"
cal.MaxSelectionCount = 1
cal.BringToFront()
cal.Location = New Point(Me.Location.X + 5, Me.Location.Y + 25)
Me.Parent.Controls.Add(cal)
cal.Hide()
_isCalendarVisible = False
End Sub
'Returns the currently selected date from the TextBox field
Public ReadOnly Property CurrentSelectedDate()
Get
Return _currentSelectedDate
End Get
End Property
'Display calendar
Private Sub ShowCalendar()
'Close any other custom date controls that are open on the parent form
Dim cont As Control
For Each cont In Parent.Controls
If (cont.GetType().Name = "CustomDatePicker") Then
CType(cont, CustomDatePicker).HideCalendar()
End If
Next
'display the calendar
If Not (_isCalendarVisible) Then
tbxSelectedDate.BackColor = Color.Cornsilk
cal.BringToFront()
cal.Show()
cal.Focus()
_isCalendarVisible = True
btnCalendarToggle.Checked = True
End If
End Sub
'Hide the Calendar
Private Sub HideCalendar()
If (_isCalendarVisible) Then
tbxSelectedDate.BackColor = Color.White
cal.Hide()
_isCalendarVisible = False
btnCalendarToggle.Checked = False
tbxSelectedDate.Focus()
End If
End Sub
'Display the selected datetime into the textbox
Private Sub SetDateTime()
Me.tbxSelectedDate.Text = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
_currentSelectedDate = FormatDateTime(cal.SelectionRange.Start, DateFormat.LongDate)
RaiseEvent OnDateTimeSet(Me, _currentSelectedDate)
End Sub
'Event when selection is made in the Calendar
Private Sub Calendar_Selection(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles cal.DateSelected
SetDateTime()
HideCalendar()
End Sub
'Handle the keyboard events associated with the calendar control
Private Sub Calendar_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles cal.KeyPress
If e.KeyChar = ChrW(Keys.Return) Then
SetDateTime()
HideCalendar()
ElseIf e.KeyChar = ChrW(Keys.Escape) Then
HideCalendar()
End If
End Sub
'Handles keypresses on the textbox field
Private Sub tbxSelectedDate_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbxSelectedDate.KeyUp
If (e.KeyCode = Keys.Down) Then
ShowCalendar()
ElseIf (e.KeyCode = Keys.Delete) Then
tbxSelectedDate.Text = ""
End If
End Sub
'Show the calendar when button is clicked
Private Sub btnCalendarToggle_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnCalendarToggle.MouseUp
ToggleCalendar()
End Sub
'Show the calendar when button is 'clicked' via ENTER on keyboard
Private Sub btnCalendarToggle_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles btnCalendarToggle.KeyPress
If e.KeyChar = ChrW(Keys.Return) Then
ToggleCalendar()
End If
End Sub
'Toggle calender. If on, turn off. If off, turn on.
Private Sub ToggleCalendar()
If Not (_isCalendarVisible) Then
ShowCalendar()
btnCalendarToggle.Checked = True
Else
HideCalendar()
btnCalendarToggle.Checked = False
End If
End Sub
'When textbox value is changed, check to see if it was cleared. If cleared, raiseevent.
Private Sub tbxSelectedDate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbxSelectedDate.TextChanged
If (tbxSelectedDate.Text = "") Then
_currentSelectedDate = Nothing
RaiseEvent OnDateCleared(Me)
End If
End Sub
Upvotes: 0
Reputation: 12795
I would use the OnValueChanged event. After they change the value, ask the question. If they answer wrong (Example - Q: Are you sure? A: No.) then reset the datepicker and return focus to it.
This example is a little messy but it works.
Private is_reset As Boolean = False
Private Sub DateTimePicker1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged
Dim answer As Integer
If Not is_reset Then
answer = MsgBox("Are you Sure?", MsgBoxStyle.YesNo)
is_reset = False
End If
If answer = MsgBoxResult.No Then
is_reset = True
DateTimePicker1.Value = Now
DateTimePicker1.Select()
End If
Upvotes: 1
Reputation: 116498
"Select a date" means:
So, how about a combination of OnCloseUp
and OnValidate
/OnLeave
?
Start by watching for OnValueChanged
events. Set a changed flag if one fires.
If they select with the mouse, you can bring up the prompt with OnCloseUp
and reset your changed flag. Then watch for OnValueChanged
events again.
When OnValidate
or OnLeave
fires, and your flag is set (presumably after changing the date with the keyboard), then bring up the prompt.
Upvotes: 1