为什么我不能在设计时在XAML中使用CultureInfo.CurrentCulture?

时间:2016-02-01 11:22:17

标签: c# wpf xaml globalization

我有以下XAML:

<TextBlock Text="{Binding Source={x:Static s:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}"/>
带有s:DateTime.Now

xmlns:s="clr-namespace:System;assembly=mscorlib"在运行时和设计模式下都能正常工作(Visual Studio 2015 Enterprise)。

但是,如果我对CultureInfo.CurrentCulture尝试相同,那么这只在运行时工作,并在设计模式(xmlns:c="clr-namespace:System.Globalization;assembly=mscorlib")中给出错误:

<TextBlock Text="{Binding Source={x:Static s:DateTime.Now}, ConverterCulture={x:Static c:CultureInfo.CurrentCulture}, StringFormat=Date: {0:dddd, MMMM dd}}"/>

我没有找到解决方法。我只是想了解DateTime.NowCultureInfo.CurrentCulture之间的区别,以及为什么其中一个有效,另一个没有。

3 个答案:

答案 0 :(得分:2)

我知道你没有要求解决方法,我无法回答你原来的问题。

我仍然希望发布我的解决方案,以防其他人(例如我)偶然发现您的问题寻找解决方法。

如果在CustomBinding类中设置ConverterCulture并在xaml中使用此CustomBinding而不是Binding,它也可以在设计时使用。

public class CultureAwareBinding : System.Windows.Data.Binding
{
    public CultureAwareBinding()
    {
        ConverterCulture = CultureInfo.CurrentCulture;
    }
}

你可以在你的xaml中使用它。

<TextBlock Text="{CultureAwareBinding Source={x:Static s:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}"/>

作为额外的好处,如果需要,您可以稍后在一个地方更改ConverterCulture。你也可以设置像StringFormat这样的其他属性。

答案 1 :(得分:0)

我已经看到了同样的行为,最好的回应是将CurrentCulture和CurrentUICulture看作是设计时的东西,除非你设置它。 与许多其他WPF表示结构一样,有时您的视图模型或其他属性需要考虑设计时间,以便您的可视元素在VS设计器中按预期显示。例如,Galasoft MVVM框架包含IsDesignTime属性。您可以使用它(或您自己的框架提供的任何内容)来特殊情况下,如果IsDesignTime为true,则将其设置为适合显示的某个值。这很方便,例如,当您想要查看将该文化设置为其他语言时的显示方式。

因此,对于您的示例,假设您确实使用MVVM类型的体系结构 - 您可能希望将TextBlock Text属性绑定到您自己的视图模型属性,并让 属性参与确定当前的DateTime和CurrentCulture。

一个注意事项:请记住,在桌面应用程序上使用WPF时,Window或UserControl ctor不会在设计时环境中执行 - 仅在运行时。在你意识到这一点之前,这可能会让人感到困惑。

答案 2 :(得分:0)

不久前我遇到了同样的问题,我强烈建议使用这个金块包进行本地化。它很容易使用。 https://www.nuget.org/packages/WpfLocalizeExtension/

示例AssemblyName = Application

RessourceFile = MainApplication.resx

Ressource1Key1 =测试

如果你使用的是MVVM,那么这里有一些代码片段。

XAML

    xmlns:lex="http://wpflocalizeextension.codeplex.com"
    lex:LocalizeDictionary.DesignCulture="en"
    lex:ResxLocalizationProvider.DefaultAssembly="AssemblyName"
    lex:ResxLocalizationProvider.DefaultDictionary="ressourceName"

为标签,按钮等定义内容......

<Label Content="{lex:Loc AssemblyName:ResourceName:ResourceKey}">
<Label Content="{lex:Loc Application:MainApplication:Test}">

在ViewModel中您想将按钮绑定到命令FrenchUI,EnglishUI

private void FrenchUI()
    {
        LocalizeDictionary.Instance.SetCurrentThreadCulture = true;
        LocalizeDictionary.Instance.Culture = new CultureInfo(ConfigurationManager.AppSettings["Culture"])//fr-CA;
    }

    private void EnglishUI()
    {
        LocalizeDictionary.Instance.SetCurrentThreadCulture = true;
        LocalizeDictionary.Instance.Culture = new CultureInfo(ConfigurationManager.AppSettings["CultureUS"]);//en-US
    }