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

时间:2022-02-17 16:36:21

I have the following XAML:

我有以下XAML:

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

s:DateTime.Now with xmlns:s="clr-namespace:System;assembly=mscorlib" works fine at runtime as well as in design mode (Visual Studio 2015 Enterprise).

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

But if I try the same with CultureInfo.CurrentCulture, then this works at runtime only and gives me an error in design mode (xmlns:c="clr-namespace:System.Globalization;assembly=mscorlib"):

但是如果我尝试使用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}}"/>

I'm not looking for a workaround. I am only trying to understand the difference between DateTime.Now and CultureInfo.CurrentCulture and why one of them works and the other one doesn't.

我不是在寻找一种解决方法。我只是想了解DateTime.Now和CultureInfo.CurrentCulture之间的区别,以及为什么其中一个工作而另一个不工作。

3 个解决方案

#1


1  

I know you did not ask for a workaround and I cannot answer your original question.

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

I still want to post my solution in case others, like me, stumble across your question looking for a workaround.

我仍然想发布我的解决方案,以防其他人,像我一样,偶然发现你的问题寻找解决方法。

If you set your ConverterCulture in a CustomBinding class and use this CustomBinding instead of Binding in you xaml, it works at design time too.

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

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

You can use it in your xaml like this.

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

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

As an additional benefit this allows you to change the ConverterCulture later in one single place if needed. Also you can set other properties like StringFormat like this.

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

#2


0  

I have seen this same behavior, and the best response is to regard CurrentCulture and CurrentUICulture as something that is not avail at design-time unless you set it. As with many other WPF presentation constructs, sometimes your view-model or other properties need to take the design-time into consideration so that your visual elements display as expected in your VS designer. For example, the Galasoft MVVM framework includes a IsDesignTime property. You can use that (or whatever your own framework provides) to special-case a property to, if IsDesignTime is true, set it to some value suitable for display. This is handy as, for example, when you want to see how it appears when you set that culture to other languages.

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

Thus for your example, assuming you are indeed using a MVVM type of architecture -- you may want to bind your TextBlock Text property to your own view-model property, and have that property attend to determining the current DateTime and the CurrentCulture.

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

One note: remember that with WPF on desktop applics, the Window or UserControl ctor is not executed within the design-time environment -- only at runtime. That can get confusing until you realize that.

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

#3


0  

I had the same problems not so long ago, I would highly suggest using this nugget packet for localisation. It is pretty easy to use. https://www.nuget.org/packages/WpfLocalizeExtension/

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

Example AssemblyName = Application

示例AssemblyName = Application

RessourceFile = MainApplication.resx

RessourceFile = MainApplication.resx

Ressource1Key1 = Test

Ressource1Key1 =测试

If you are using MVVM here is some code snippet.

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

XAML

XAML

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

Defining Content for label,button etc...

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

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

In ViewModel You want to bind your button to command FrenchUI,EnglishUI

在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
    }

#1


1  

I know you did not ask for a workaround and I cannot answer your original question.

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

I still want to post my solution in case others, like me, stumble across your question looking for a workaround.

我仍然想发布我的解决方案,以防其他人,像我一样,偶然发现你的问题寻找解决方法。

If you set your ConverterCulture in a CustomBinding class and use this CustomBinding instead of Binding in you xaml, it works at design time too.

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

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

You can use it in your xaml like this.

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

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

As an additional benefit this allows you to change the ConverterCulture later in one single place if needed. Also you can set other properties like StringFormat like this.

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

#2


0  

I have seen this same behavior, and the best response is to regard CurrentCulture and CurrentUICulture as something that is not avail at design-time unless you set it. As with many other WPF presentation constructs, sometimes your view-model or other properties need to take the design-time into consideration so that your visual elements display as expected in your VS designer. For example, the Galasoft MVVM framework includes a IsDesignTime property. You can use that (or whatever your own framework provides) to special-case a property to, if IsDesignTime is true, set it to some value suitable for display. This is handy as, for example, when you want to see how it appears when you set that culture to other languages.

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

Thus for your example, assuming you are indeed using a MVVM type of architecture -- you may want to bind your TextBlock Text property to your own view-model property, and have that property attend to determining the current DateTime and the CurrentCulture.

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

One note: remember that with WPF on desktop applics, the Window or UserControl ctor is not executed within the design-time environment -- only at runtime. That can get confusing until you realize that.

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

#3


0  

I had the same problems not so long ago, I would highly suggest using this nugget packet for localisation. It is pretty easy to use. https://www.nuget.org/packages/WpfLocalizeExtension/

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

Example AssemblyName = Application

示例AssemblyName = Application

RessourceFile = MainApplication.resx

RessourceFile = MainApplication.resx

Ressource1Key1 = Test

Ressource1Key1 =测试

If you are using MVVM here is some code snippet.

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

XAML

XAML

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

Defining Content for label,button etc...

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

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

In ViewModel You want to bind your button to command FrenchUI,EnglishUI

在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
    }