How to set and change the culture in WPF

后端 未结 7 1595
孤独总比滥情好
孤独总比滥情好 2020-11-30 00:02

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:

相关标签:
7条回答
  • 2020-11-30 00:30

    Adaptive OverrideMetadata

    Some form of reloading is inevitable, because changing a control's Language property doesn't make it update its text.

    However, there's a way of overriding the metadata which allows you to set it once and have new controls automatically use the current culture:

    FrameworkElement.LanguageProperty.OverrideMetadata(
        typeof(FrameworkElement),
        new FrameworkPropertyMetadata(
            System.Windows.Markup.XmlLanguage.Empty,
            default(PropertyChangedCallback),
            _CoerceCurrentXmlLang));
    

    where the CoerceValueCallback is

    private static object _CoerceCurrentXmlLang(DependencyObject d, object baseValue)
    {
        var lang = baseValue as System.Windows.Markup.XmlLanguage;
        var culture = System.Globalization.CultureInfo.CurrentUICulture;
        return lang != null && lang.IetfLanguageTag.Equals(culture.Name, StringComparison.InvariantCultureIgnoreCase)
            ? lang
            : System.Windows.Markup.XmlLanguage.GetLanguage(culture.Name);
    }
    

    By itself this isn't quite enough, because newly created controls will get the default value System.Windows.Markup.XmlLanguage.Empty without it being coerced. However, if you then set xml:lang="" in your windows' XAML, that will be coerced, and then each new control will see that it inherits a value from its parent and will coerce it. The result is that new controls added to that window will use the current language.

    PS As with many things in WPF, it would be quite a bit simpler if they hadn't been so keen to keep things internal. DefaultValueFactory would be a far more elegant way of doing this.

    Reloading

    The most extreme, but therefore reliable, way of reloading is just to create a new main window and discard the old one.

    Almost as extreme but not quite is to arrange for the language setting to be changed only in a very simple pane of the main window with very little loaded, and that very little to be entirely databound to a viewmodel which supports forcing a property changed notification for everything.

    Existing answers to this question have other suggestions.

    0 讨论(0)
提交回复
热议问题