问题
Using the traditional DateTimePicker control in a winforms environment in a vb.net or c# application I need to change how the week is displayed from the normal Sunday through Saturday to Tuesday through Monday. I have scoured Google and Stack and found nothing on this. I have no issue with creating a custom control. I just don't know where to start.
回答1:
You can use SendMessage to send a MCM_SETFIRSTDAYOFWEEK message to the MonthCalendar of the DateTimePicker (read the notes related to this message in the Docs).
You first send a DTM_GETMONTHCAL message to get the handle of the MonthCalendar control. As shown, you can send this message in the DropDown
event handler of the DateTimePicker.
If the handle is valid, set the first day sending MCM_SETFIRSTDAYOFWEEK
.
The lParam
value determines the first day shown in the MonthCalendar:
0
= Monday, 1
= Tuesday etc.
If you want to build a custom control (IMO, preferable), you can find one pre-built here:
How can I set the DateTimePicker dropdown to select Years or Months only?
It shows how to deal with the DateTimePicker and its MonthCalendar dropdown, to change the current View and similar tasks.
internal const int DTM_FIRST = 0x1000;
internal const int DTM_GETMONTHCAL = DTM_FIRST + 8;
internal const int MCM_FIRST = 0x1000;
internal const int MCM_SETFIRSTDAYOFWEEK = MCM_FIRST + 15;
internal enum MCWeekDay : int
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
internal void MonthCalendarSetFirstDayOfWeek(IntPtr dtpHandle, MCWeekDay weekDay)
{
IntPtr hWndCal = SendMessage(dtpHandle, DTM_GETMONTHCAL, 0, 0);
if (hWndCal != IntPtr.Zero) {
SendMessage(hWndCal, MCM_SETFIRSTDAYOFWEEK, 0, (int)weekDay);
}
}
private void dateTimePicker1_DropDown(object sender, EventArgs e)
{
MonthCalendarSetFirstDayOfWeek((sender as Control).Handle, MCWeekDay.Tuesday);
}
VB.Net version:
Imports System.Runtime.InteropServices
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_SETFIRSTDAYOFWEEK As Integer = MCM_FIRST + 15
Friend Enum MCWeekDay As Integer
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
End Enum
<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
Friend Sub MonthCalendarSetFirstDayOfWeek(dtpHandle As IntPtr, weekDay As MCWeekDay)
Dim hWndCal As IntPtr = SendMessage(dtpHandle, DTM_GETMONTHCAL, 0, 0)
If hWndCal <> IntPtr.Zero Then
SendMessage(hWndCal, MCM_SETFIRSTDAYOFWEEK, 0, weekDay)
End If
End Sub
Private Sub DateTimePicker1_DropDown(sender As Object, e As EventArgs) Handles DateTimePicker1.DropDown
MonthCalendarSetFirstDayOfWeek(DirectCast(sender, Control).Handle, MCWeekDay.Tuesday)
End Sub
来源:https://stackoverflow.com/questions/61696967/change-week-display-in-datetimepicker-control