1

我想将时间 DateTimePicker 格式化为 24 小时。

我使用了以下代码,时间实际上更改为 24 小时。
现在的问题是,当设备使用阿拉伯语区域或英语区域时,日期格式会出现不受欢迎的形状。
无论设备的区域有多么不同,我都希望日期的方向不会改变。

我希望日期的方向是小时、分钟和上午/下午,如图所示,无论时区如何。

在此处输入图像描述

我的代码:

If Thread.CurrentThread.CurrentCulture.DisplayName.Contains("arab".ToLower)  Then
    ROSYUPDATE_F.DateTimePicker.Format = System.Windows.Forms.DateTimePickerFormat.Custom
    ROSYUPDATE_F.DateTimePicker.CustomFormat = "HH:mm tt" 
Else

    ROSYUPDATE_F.DateTimePicker.Format = System.Windows.Forms.DateTimePickerFormat.Custom
    ROSYUPDATE_F.DateTimePicker.CustomFormat = " tt mm:HH"
End If

从所需格式更改时间的动画

在此处输入图像描述

4

1 回答 1

1

当您更改区域设置时,Thread.CurrentThread.CurrentCulture或 ( CultureInfo.CurrentCulture) 不会自动更新。
您可以调用CultureInfo.ClearCachedData()来重置内部CultureData存储的设置并重新加载值。

要在用户设置更改时更新您的 UI,您可以处理系统在这些设置更改时发送的通知。

确认这些通知的一种简单方法是处理当系统设置中的某些内容发生更改时发送到所有顶级 Windows的WM_SETTINGCHANGE消息。 这些通知有些通用(阅读有关它的文档),但您可以大致了解检查和值发生了什么变化。
WParamLParam

在您的表单中覆盖WndProc以处理WM_SETTINGCHANGE消息。
当您获得一个时,请验证哪些设置已更改并根据此信息采取行动。

在这种情况下,当区域(用户)设置更改时,WParam设置为0LParam指向一个字符串,该字符串读取为"intl".
然后,如果 Language 是 RTL(或非特定的阿拉伯语 - 你得到什么CultureInfo.GetCultureInfo("AR")),设置你的自定义格式,否则你可以设置默认值ShortTimePattern,或者其他。
(假设 DateTimePicker 控件名为DateTimePicker1

Private Const WM_SETTINGCHANGE As Integer = &H1A

Protected Overrides Sub WndProc(ByRef m As Message)
    Select Case m.Msg
        Case WM_SETTINGCHANGE
            Dim lparmSetting = Marshal.PtrToStringAuto(m.LParam)
            If m.WParam.ToInt32() = 0 AndAlso lparmSetting.Equals("intl") Then
                CultureInfo.CurrentCulture.ClearCachedData()
                DateTimePicker1.CustomFormat = If(CultureInfo.CurrentCulture.TextInfo.IsRightToLeft,
                    "tt mm:hh", CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern)
            End If
    End Select
    MyBase.WndProc(m)
End Sub

次要:
由于您的自定义格式不完全是标准的,因此您在首次加载表单时可能会有不同的行为,具体取决于运行您的应用程序的机器的当前区域设置。您可以向自己
发送WM_SETTINGCHANGE消息,并按照说明进行设置,以便在启动时自动更新和格式化 DateTimePicker。WParamLParam

Form.Load(或OnLoad()OnShown()OnHandleCreated())中,您可以添加:

Imports System.Runtime.InteropServices

Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)
    SendMessage(Me.Handle, WM_WININICHANGE, IntPtr.Zero, Marshal.StringToHGlobalAuto("intl"))
End Sub

SendMessage 声明:

<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Friend Shared Function SendMessage(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
End Function
于 2021-08-06T01:01:49.023 回答