在 DateTimePicker 控件中更改周显示

Change Week Display in DateTimePicker Control

在 vb.net 或 c# 应用程序的 winforms 环境中使用传统的 DateTimePicker 控件,我需要将星期的显示方式从正常的星期日到星期六更改为星期二到星期一。我搜索了 Google 和 Stack,但没有发现任何相关内容。我对创建自定义控件没有问题。我只是不知道从哪里开始。

您可以使用 SendMessage to send a MCM_SETFIRSTDAYOFWEEK 消息到 DateTimePicker 的 MonthCalendar(阅读文档中与此消息相关的注释)。

您首先发送 DTM_GETMONTHCAL 消息以获取 MonthCalendar 控件的句柄。如图所示,您可以在 DateTimePicker 的 DropDown 事件处理程序中发送此消息。
如果句柄有效,设置第一天发送MCM_SETFIRSTDAYOFWEEK.
lParam 值确定 MonthCalendar 中显示的第一天:

0 = 星期一,1 = 星期二等

如果你想构建一个自定义控件(IMO,最好),你可以在这里找到一个预构建的:

它展示了如何处理 DateTimePicker 及其 MonthCalendar 下拉菜单,以更改当前视图和类似任务。

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版本

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