如何设置和改变文化的WPF [英] How to set and change the culture in WPF
问题描述
我有一个.NET 4.0的WPF应用程序,用户可以更改语言(文化) 我只是让用户选择一种语言,创建相应的CultureInfo,并设置:
I have a .NET 4.0 WPF application where the user can change the language (culture) I simply let the user select a language, create a corresponding CultureInfo and set:
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
在C#code能正常工作。然而,在WPF控件的文化仍然是EN-US。这意味着,例如,日期将在美国的格式,而不是什么是正确的当前区域性显示出来。
In the C# code this works fine. However in the WPF controls the culture is still en-US. This means for example that dates will be shown in the US format instead of whatever is correct for the current culture.
显然,这是不是一个错误。根据MSDN和几个博客帖子和文章对计算器的WPF语言不会自动跟随当前的文化。它为en-US,直到你做到这一点:
Apparently, this is not a bug. According to MSDN and several blog posts and articles on StackOverflow the WPF language does not automatically follow the current culture. It is en-US until you do this:
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentUICulture.IetfLanguageTag)));
例如,见<一href="http://stackoverflow.com/questions/520115/stringfomat-localization-problem/520334#520334">StringFomat本地化问题。
我不完全明白是怎么回事。似乎所有frameworkelements的语言属性被设置为当前文化。无论如何,它的工作原理。我这样做时,应用程序启动了,现在所有的控件正常工作,而如日期是根据当前培养格式化。
I do not completely understand what is going on here. It seems the Language property on all frameworkelements is set to the current culture. Anyway, it works. I do this when the application starts up and now all controls works as expected, and e.g. dates is formatted according to the current culture.
但现在的问题:根据MSDN FrameworkElement.LanguageProperty.OverrideMetadata code>只能被调用一次。事实上,如果我再次调用它(当用户更改语言),它会抛出异常。所以我还没有真正解决我的问题。
But now the problem: According to MSDN FrameworkElement.LanguageProperty.OverrideMetadata
can only be called once. And indeed, if I call it again (when the user changes the language) it will throw an exception. So I haven't really solved my problem.
问题:我怎样才能可靠地在WPF更新文化不止一次,并在我的应用程序生命周期的任何时间
The question: How can I reliably update the culture in WPF more than once and at any time in my applications life cycle?
(我研究的时候发现这一点:<一href="http://www.nbdtech.com/Blog/archive/2009/03/18/getting-a-wpf-application-to-pick-up-the-correct-regional.aspx">http://www.nbdtech.com/Blog/archive/2009/03/18/getting-a-wpf-application-to-pick-up-the-correct-regional.aspx 而且看起来他有一些东西在那里工作。但是,我无法想象如何做到这一点在我的应用程序。看来我将不得不更新所有打开的窗口和控制语言和刷新所有现有绑定等。)
(I found this when researching: http://www.nbdtech.com/Blog/archive/2009/03/18/getting-a-wpf-application-to-pick-up-the-correct-regional.aspx and it seems he has something working there. However, I can't imagine how to do this in my application. It seems I would have to update the language in all open windows and controls and refresh all existing bindings etc.)
推荐答案
我从来没有发现一种方法做什么我问的问题。 就我而言,我结束了通过让所有的用户控件从包含该超类继承解决它:
I never found a way to do exactly what I asked for in the question. In my case I ended up solving it by having all my usercontrols inherit from a superclass that contained this:
/// <summary>
/// Contains shared logic for all XAML-based Views in the application.
/// Views that extend this type will have localization built-in.
/// </summary>
public abstract class ViewUserControl : UserControl
{
/// <summary>
/// Initializes a new instance of the ViewUserControl class.
/// </summary>
protected ViewUserControl()
{
// This is very important! We make sure that all views that inherit
// from this type will have localization built-in.
// Notice that the following line must run before InitializeComponent() on
// the view. Since the supertype's constructor is executed before the type's
// own constructor (which call InitializeComponent()) this is as it
// should be for classes extending this
this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
}
}
当用户改变了语言,我再创建任何用户控件当前正在运行的新实例。
When the user changes the language I then create new instances of any usercontrols that are currently running.
这解决了我的问题。不过,我仍想办法做到这一点自动(即无需跟踪任何实例化对象)。
This solved my problem. However, I would still like a way to do this "automatically" (i.e. without having to keep track of any instantiated objects).
这篇关于如何设置和改变文化的WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!