WPF 中的多语言

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/814600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:21:08  来源:igfitidea点击:

Multilanguage in WPF

wpfxamlglobalizationmultilingual

提问by Jonathan

Can you recommend a good way to implement a Multilanguage system for a WPF app? The method I'm using right now involves XML, classes and a xaml extension. It Works fine in most of cases, but when I have to deal with dynamic labels or dynamic text in general it require some extra effort. I would like to let the programmer working only in the main problem and forgot the lang issues.

您能推荐一种为 WPF 应用程序实现多语言系统的好方法吗?我现在使用的方法涉及 XML、类和 xaml 扩展。它在大多数情况下都可以正常工作,但是当我必须处理动态标签或动态文本时,通常需要一些额外的努力。我想让程序员只在主要问题上工作而忘记了语言问题。

采纳答案by CSharper

I am using the WPF Localization Extension. It is a really easy way to localize any type of DependencyPropertyon DependencyObjects.

我正在使用WPF 本地化扩展。这是对任何类型的DependencyPropertyon进行本地化的非常简单的方法DependencyObject

  • is in a real stable state
  • supports binding-like writing style like Text = {LocText ResAssembly:ResFile:ResKey}
  • works with the .resx-fallback mechanism (e.g. en-us -> en -> independent culture)
  • supports culture forcing (e.g. "this has to be English all the time")
  • works with normal dependency properties
  • works with control templates
  • can be used in XAML (really :P) without any additional namespaces
  • can be used in code behind to bind localized values to dynamic generated controls
  • implements INotifyPropertyChangedfor advanced use
  • supports string formatting e.g. "this is the '{0}' value"
  • supports prefix and suffix values (currently with LocTextextension)
  • is in use in productive systems (like my public relation product)
  • switching of the language to runtime affects NOtimeslice
  • can be used with any resource file (.resx) across all assemblies (also the dynamic loaded one at runtime)
  • doesn't need any initializing process (like "call xyz to register a special localize dictionary")
  • is available at design-time (MS Expression Blend, MS Visual Studio 2008 (Normal and SP1)
  • change of the chosen language is possible at design-time
  • can localize any type of data type, as long as a converter (TypeConverter) for it exists (extends LocalizeExtension)
  • has built in support for Text, upper Text, lower Text, Images, Brushes, Doubleand Thickness
  • doesn't affects any memory leaks
  • leaves the UIDproperty untouched
  • offers a SpecificCultureto use as IFormatProvider(e.g. (123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20"or "123,20")
  • offers some functionality to check and get resource values in code behind
  • doesn't alter the culture on Thread.CurrentCultureor Thread.CurrentUICulture(can be changed easily)
  • 处于真正稳定的状态
  • 支持类似绑定的写作风格 Text = {LocText ResAssembly:ResFile:ResKey}
  • 使用 .resx-fallback 机制(例如 en-us -> en -> 独立文化)
  • 支持文化强制(例如“这必须一直是英语”)
  • 使用正常的依赖属性
  • 使用控件模板
  • 可以在 XAML 中使用(真的:P)而无需任何额外的命名空间
  • 可以在后面的代码中使用,将本地化的值绑定到动态生成的控件
  • 工具INotifyPropertyChanged的高级使用
  • 支持字符串格式,例如 "this is the '{0}' value"
  • 支持前缀和后缀值(目前有LocText扩展)
  • 在生产系统中使用(比如我的公关产品)
  • 语言来运行的开关会影响NO时间片
  • 可以与.resx所有程序集中的任何资源文件 ( )一起使用(也是在运行时动态加载的)
  • 不需要任何初始化过程(比如“调用 xyz 来注册一个特殊的本地化字典”)
  • 在设计时可用(MS Expression Blend、MS Visual Studio 2008(普通和 SP1)
  • 可以在设计时更改所选语言
  • 可以本地化任何类型的数据类型,只要它的转换器(TypeConverter)存在(扩展LocalizeExtension
  • 内置了对Text、 upper Text、 lower TextImages、BrushesDoubleThickness
  • 不影响任何内存泄漏
  • 保持UID财产不变
  • 提供一个SpecificCulture用作IFormatProvider(例如(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20""123,20"
  • 提供一些功能来检查和获取代码背后的资源值
  • 不会改变Thread.CurrentCulture或的文化Thread.CurrentUICulture(可以很容易地改变)

回答by Andre van Heerwaarde

Follow these steps:

按着这些次序:

1)Place all Stringfragments in a separate resource file.

1)将所有String片段放在一个单独的资源文件中。

Example: StringResources.xaml:

示例StringResources.xaml::

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">

    <!-- String resource that can be localized -->
    <system:String x:Key="All_Vehicles">All Vehicles</system:String>

</ResourceDictionary>

2)Make copies for each language and add them (translated) to the merged dictionaries. Don't forget to add the country's ISO code to make things easier.

2)为每种语言制作副本并将它们(翻译)添加到合并的词典中。不要忘记添加国家/地区的 ISO 代码以简化操作。

Example App.xaml:

示例App.xaml

<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="StringResources.de-DE.xaml" />
                <ResourceDictionary Source="StringResources.nl-NL.xaml" />
                <ResourceDictionary Source="StringResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

The last resource file with strings will be used to replace text parts in code.

最后一个带有字符串的资源文件将用于替换代码中的文本部分。

3a)Use the text parts from the Stringtable:

3a)使用String表中的文本部分:

Example Window1.xaml:

示例Window1.xaml

<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
    <Grid>
        <Button Margin="51,82,108,129" Name="AllVehiclesButton" 
                Content="{StaticResource All_Vehicles}"/>
    </Grid>
</Window>

3b)Load the resource from code (Only use this code if you don't want to set via XAML):

3b)从代码加载资源(如果您不想设置 via ,请仅使用此代码XAML):

void PageLoad()
{
  string str = FindResource("All_Vehicles").ToString();
}

4)Switch to new culture at start of application:

4)在应用程序开始时切换到新文化:

Codesnippet from App.xaml.cs:

代码片段来自App.xaml.cs

public static void SelectCulture(string culture)    
{      
    if (String.IsNullOrEmpty(culture))
        return;

    //Copy all MergedDictionarys into a auxiliar list.
    var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();

    //Search for the specified culture.     
    string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
    var resourceDictionary = dictionaryList.
        FirstOrDefault(d => d.Source.OriginalString == requestedCulture);

    if (resourceDictionary == null)
    {
        //If not found, select our default language.             
        requestedCulture = "StringResources.xaml";
        resourceDictionary = dictionaryList.
            FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
    }

    //If we have the requested resource, remove it from the list and place at the end.     
    //Then this language will be our string table to use.      
    if (resourceDictionary != null)
    {
        Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
        Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
    }

    //Inform the threads of the new culture.     
    Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

}

回答by Terenzio Berni

Using this article I've managed to easily use resource files to handle multilingual WPF windows. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspxYou should give it a check because it's really simple and effective.

使用本文,我设法轻松地使用资源文件来处理多语言 WPF 窗口。 http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx您应该检查一下,因为它非常简单有效。

回答by Wilka

Josh Smith wrote an in-depth tutorial about his preferred method for this: Creating an Internationalized Wizard in WPF.

Josh Smith 写了一篇关于他的首选方法的深入教程:在 WPF 中创建国际化向导

It might point you towards a big redesign (it's a MVVM solution), but using MVVM seems worth it for other reasons as well.

它可能会引导您进行重大的重新设计(这是一个MVVM 解决方案),但出于其他原因,使用 MVVM 似乎也值得。