WPF中的多语言

WPF中的多语言,wpf,xaml,globalization,multilingual,Wpf,Xaml,Globalization,Multilingual,你能为WPF应用程序推荐一种实现多语言系统的好方法吗?我现在使用的方法包括XML、类和xaml扩展。它在大多数情况下都可以正常工作,但当我不得不处理动态标签或动态文本时,通常需要一些额外的工作。我想让程序员只处理主要问题,而忘记语言问题。遵循以下步骤: 1)将所有String片段放在单独的资源文件中 示例:StringResources.xaml: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml

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

遵循以下步骤:

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

示例:
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>
<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>
<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>
最后一个带字符串的资源文件将用于替换代码中的文本部分

3a)使用
字符串
表中的文本部分:

示例
Window1.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>
<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>
<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>
4)开始使用时切换到新培养基:

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);

}

Josh Smith写了一篇关于他对此首选方法的深入教程:

这可能会让您面临一个大的重新设计(这是一个很好的选择),但出于其他原因,使用MVVM似乎也是值得的。

我正在使用。在
DependencyObject
s上本地化任何类型的
dependencProperty
是一种非常简单的方法

  • 处于真正稳定的状态
  • 支持像
    Text={LocText-ResAssembly:ResFile:ResKey}
  • 使用.resx回退机制(例如en-us->en->independent culture)
  • 支持文化强制(例如,“这必须是英语的所有时间”)
  • 使用普通依赖项属性
  • 使用控件模板
  • 可以在XAML(真的是:P)中使用,而无需任何其他名称空间
  • 可以在代码隐藏中用于将本地化值绑定到动态生成的控件
  • 实现INotifyPropertyChanged
    以供高级使用
  • 支持字符串格式,例如
    “这是{0}”值”
  • 支持前缀和后缀值(当前具有
    LocText
    扩展名)
  • 在生产系统中使用(如我的公共关系产品)
  • 将语言切换到运行时会影响时间片
  • 可以在所有程序集(以及运行时动态加载的程序集)中与任何资源文件(
    .resx
    )一起使用
  • 不需要任何初始化过程(如“调用xyz注册特殊的本地化词典”)
  • 在设计时可用(MS Expression Blend、MS Visual Studio 2008(普通和SP1)
  • 可在设计时更改所选语言
  • 可以本地化任何类型的数据类型,只要其存在转换器(
    TypeConverter
    )(extends
    LocalizeExtension
  • 内置了对
    文本
    、上部
    文本
    、下部
    文本
    、图像
    s、
    画笔
    es、
    双重
    厚度
  • 不会影响任何内存泄漏
  • 使
    UID
    属性保持不变
  • 提供一个
    SpecificCulture
    用作
    IFormatProvider
    (例如
    (123.20).ToString(LocalizeDictionary.SpecificCulture)=“123.20”
    “123,20”
  • 提供一些功能来检查和获取代码隐藏中的资源值
  • 不更改
    线程.CurrentCulture
    线程.CurrentUICulture
    上的区域性(可以轻松更改)

通过本文,我可以轻松地使用资源文件来处理多语言WPF窗口。
你应该检查一下,因为它非常简单有效。

喜欢你的建议。需要补充的东西:我认为我们可以使用
{StaticResource resKey}
使应用程序在运行时可以切换实际上,只要在使用资源的任何地方指定{DynamicResource resKey},然后在运行时随时调用SelectCulture(culture)方法,它将动态地将所有字符串更新为新区域性。而不是:string str=FindResource(“所有车辆”).ToString();使用:Application.Current.Resources[“所有车辆”]在执行期间是否有任何方法可以更改它?您可以在运行时调用该方法,例如,在单击带有国旗的按钮后。如果您正在构建一个大型应用程序,并且希望引用来自WPF、ASP.NET或其他类库的同一文件,那么我认为这是一个更好的解决方案:无文档或者关于如何使用这个的教程?现在有一个文档可供使用