问题描述
我有一个 .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# 代码中,这可以正常工作.然而,在 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 和 StackOverflow 上的几篇博客文章和文章,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)));
请参阅例如 StringFormat 本地化问题 in wpf.
我不完全理解这里发生了什么.似乎所有框架元素的 Language 属性都设置为当前文化.无论如何,它有效.我在应用程序启动时执行此操作,现在所有控件都按预期工作,例如日期根据当前文化格式化.
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
只能调用一次.事实上,如果我再次调用它(当用户更改语言时)它会抛出异常.所以我还没有真正解决我的问题.
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?
(我在研究时发现了这个: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 中设置和更改区域性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!