【问题标题】:Why can't I use CultureInfo.CurrentCulture in XAML at design time?为什么我不能在设计时在 XAML 中使用 CultureInfo.CurrentCulture?
【发布时间】:2016-02-01 11:22:17
【问题描述】:

我有以下 XAML:

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

s:DateTime.Nowxmlns: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 之间的区别以及为什么其中一个有效而另一个无效。

【问题讨论】:

  • 它会给你什么错误?您确定是DateTime.NowCultureInfo.CurrentCulture 之间的区别,而不是SourceConverterCulture 之间的区别吗? (虽然很奇怪,但请尝试将 Source 指定为 CultureInfo.CurrentCulture,看看是否仍然会出错。)
  • 它重现了我的问题。我也尝试了@JonSkeet 的建议,问题确实是CurrentCulture。顺便说一下CurrentCulture 的文档说:An object that represents the culture used by the current thread.。这不是问题吗?在设计时没有“当前线程”。 DefaultThreadCurrentCultureInstalledUICultureInvariantCultureDefaultThreadCurrentUICulture 工作正常。只有CurrentCultureCurrentUICulture 起作用了。

标签: c# wpf xaml globalization


【解决方案1】:

我知道您没有要求解决方法,我无法回答您最初的问题。

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

如果您在 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。

【讨论】:

  • 虽然这确实不能回答我的问题,但它仍然是最好的答案。我已经尝试过了,它有效。谢谢!
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    示例 AssemblyName = 应用程序

    RessourceFile = MainApplication.resx

    Ressource1Key1 = 测试

    如果你使用的是 MVVM,这里有一些代码 sn-p。

    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
        }
    

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-09
      • 2012-08-26
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多