绑定时,我的DateTime格式会更改

时间:2014-03-15 14:50:53

标签: c# wpf datetime

我的总部设在英国,我的电脑始终显示英国日期格式(年/月/日)。

我的WPF项目由于某种原因将我的DateTime格式转换为US类型。这发生在我的工作机器和家用机器上。

我能够非常简单地复制这个问题

<Window x:Class="TimeIssues.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBlock Text="{Binding MyTime}"></TextBlock> <!-- the value is 1/28/2014 10:15:37 (note it is M/dd/yyyy....)
</Grid>
</Window>

在后面的代码中,只需

public partial class MainWindow : Window
{
    public MainWindow()
    {
        SetMyTime("28/01/2014 10:15:37"); //note, this is dd/MM/yyyy .... format
        this.DataContext = this;
        InitializeComponent();
    }

    private void SetMyTime(string dateTime)
    {
        DateTime dt;
        DateTime.TryParseExact(dateTime, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
        MyTime = dt; // the value is expected, showing 28/01/2014 10:15:37
    }

    public DateTime MyTime { get; set; }
}

只是为了确认这不是IT问题(或者我认为),我的PC设置为英国(并且位置也设置为英国,非unicode程序的当前语言)

enter image description here

我已阅读WPF format DateTime in TextBlock?但这无济于事(我不认为),因为该问题是关于在知道格式时设置格式的问题。

如果我将我的MyTime从DateTime更新为string,则结果是预期的(英国格式)!问题是WPF在类型为DateTime时更改格式,这是不希望的!

我的问题是2折 -

  1. 我不知道用户需要的格式(我的软件是全世界分发的)。
  2. WPF似乎无论如何都会错误地更改格式!
  3. 如何告诉WPF使用用户的区域设置?有没有办法读取操作系统设置(按照上面的屏幕截图)?

2 个答案:

答案 0 :(得分:6)

从线程的当前文化中挑选

CultureInfo,在您的情况下,这将被设置为en-US。您需要将其设置为en-GB,如下所示:

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB");

但是当你设置它时你会看到,XAML并没有选择它。要让XAML选择它,您必须覆盖FrameworkElement.LanguageProperty元数据。

覆盖OnStartup()中的App.xaml.cs方法并将此代码放在那里,您就可以了:

protected override void OnStartup(StartupEventArgs e)
{
   base.OnStartup(e);

   Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-GB");
   Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB");

   FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(
           XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}

<强>更新

  

有没有办法读取操作系统设置(按照屏幕截图   以上)?

如果您想根据为系统选择的格式选择CultureInfo,您也可以通过获取LCID for OS来实现。你就是这样做的:

[DllImport("kernel32.dll")]
private static extern int GetUserDefaultLCID();

protected override void OnStartup(StartupEventArgs e)
{
   base.OnStartup(e);

   int machineLCID = GetUserDefaultLCID();
   CultureInfo machineCultureInfo = CultureInfo.GetCultureInfo(machineLCID);
   Thread.CurrentThread.CurrentUICulture = machineCultureInfo;
   Thread.CurrentThread.CurrentCulture = machineCultureInfo;

   FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(
           XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}

答案 1 :(得分:0)

尝试类似的东西     <TextBlock Text="{Binding MyTime, ConverterCulture='en-GB'} </TextBlock>

如果失败,请尝试<TextBlock Text="{Binding MyTime, ConverterCulture='en-GB', StringFormat={}{0:dd/MM/yyyy} </TextBlock>

您可能尝试的一件事是,而不是返回DateTime对象,尝试使您的类根据运行该程序的系统的当前CultureInfo获取/设置格式化字符串。这将以您希望的方式绑定字符串,而不是en-US的默认DateTime绑定。