Reputation: 1038
At startup, I set DateTimePicker Value to the Minimum Date value.
The Date is changed to the current Date when a User clicks the DateTimePicker, using the MouseDown
event.
A TextBox is changed to the current date, but the pop-up Calendar is not updated and still shows the original Date.
Private Sub frm1_Load(sender As Object, e As EventArgs) Handles Me.Load
dtpReceiveDate.Value = clsCommon.NULL_DATE
End Sub
Private Sub dtpReceiveDate_MouseDown(sender As Object, e As MouseEventArgs) Handles dtpReceiveDate.MouseDown
dtpReceiveDate.Value = Today
End Sub
Upvotes: 2
Views: 607
Reputation: 32223
The MouseDown
event is raised after the MonthCalendar Control of your DateTimePicker has been updated with the current DateTime value.
In case the MouseDown event is generated on the Button that opens the MonthCalendar.
Clicking on the date section of the Control, doesn't cause the MonthCalendar to open.
I suggest not to use the MouseDown event to update the Value of the DateTimePicker, since this will cause the Date to reset each time a User clicks anywhere on the Control. It could be unnerving (it's up to you anyway).
You can use the DropDown
event instead: it's raised only when a User Clicks on the down-arrow Button.
▶ You cannot use the ValueChanged
event with the code shown here: this might cause a deadlock (given the nature of the Win32 Controls involved and the use of SendMessage, it's the type of deadlock that may spread to the entire System, so, don't).
The DtpUpdateMonthCalendardDate()
method here sends a DTM_GETMONTHCAL message to the DateTimePicker passed as argument.
If the Handle of the MonthCalendar is acquired successfully, it then sends a MCM_SETCURSEL message to the MonthCalendar Control to align its Date to the Date of the parent DateTimePicker.
The new Date is passed using a SYSTEMTIME structure initialized with the Value of the DateTimePicker.
Private Sub dtpReceiveDate_DropDown(sender As Object, e As EventArgs) Handles dtpReceiveDate.DropDown
dtpReceiveDate.Value = Date.Today
' If result is False, something went wrong and the Date is not set
Dim result = DtpUpdateMonthCalendardDate(dtpReceiveDate)
End Sub
Private Function DtpUpdateMonthCalendardDate(dtp As DateTimePicker) As Boolean
If Not dtp.IsHandleCreated OrElse dtp.ShowUpDown Then Return False
Dim hWndCal = SendMessage(dtp.Handle, DTM_GETMONTHCAL, 0, 0)
If hWndCal = IntPtr.Zero Then Return False
Dim sysTime = New SYSTEMTIME(dtp.Value)
Return SendMessage(hWndCal, MCM_SETCURSEL, 0, sysTime) <> 0
End Function
Win32 declarations:
Friend Const DTM_FIRST As Integer = &H1000
Friend Const DTM_GETMONTHCAL As Integer = DTM_FIRST + 8
Friend Const MCM_FIRST As Integer = &H1000
Friend Const MCM_GETCURSEL As Integer = MCM_FIRST + 1
Friend Const MCM_SETCURSEL As Integer = MCM_FIRST + 2
<StructLayout(LayoutKind.Sequential)>
Friend Structure SYSTEMTIME
Public Year As Short
Public Month As Short
Public DayOfWeek As Short
Public Day As Short
Public Hour As Short
Public Minute As Short
Public Second As Short
Public Milliseconds As Short
Public Sub New(dt As Date)
Year = CShort(dt.Year)
Month = CShort(dt.Month)
DayOfWeek = CShort(dt.DayOfWeek)
Day = CShort(dt.Day)
Hour = CShort(dt.Hour)
Minute = CShort(dt.Minute)
Second = CShort(dt.Second)
Milliseconds = CShort(dt.Millisecond)
End Sub
Public Function ToDateTime() As Date
Return New DateTime(Year, Month, Day, Hour, Minute, Second, Milliseconds)
End Function
End Structure
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Friend Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As Integer) As IntPtr
End Function
<DllImport("User32", SetLastError:=True, CharSet:=CharSet.Auto)>
Friend Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As Integer, lParam As SYSTEMTIME) As Integer
End Function
Upvotes: 3