【问题标题】:Multilanguage in WPF [closed]WPF中的多语言[关闭]
【发布时间】:2010-10-23 07:27:48
【问题描述】:

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

【问题讨论】:

    标签: wpf xaml globalization multilingual


    【解决方案1】:

    按照以下步骤操作:

    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>
    

    2) 为每种语言制作副本并将它们添加(翻译)到合并的字典中。不要忘记添加国家/地区的 ISO 代码以使事情变得更容易。

    例如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>
    

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

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

    例如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) 从代码中加载资源(如果您不想通过XAML 设置,请仅使用此代码):

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

    4) 开始申请时切换到新文化:

    来自App.xaml.cs的Codesn-p:

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

    【讨论】:

    • 喜欢你的建议。补充一点:我认为我们可以通过使用{StaticResource resKey} 使应用程序在运行时可切换
    • 实际上,只要在使用资源的地方指定 {DynamicResource resKey},然后在运行时随时调用上面的 SelectCulture(culture) 方法,它就会将所有字符串动态更新为新的文化。而不是: string str = FindResource("All_Vehicles").ToString();使用:Application.Current.Resources["All_Vehicles"] 作为字符串
    • 在执行期间有什么办法可以改变吗?
    • 您可以在运行时调用该方法,例如点击带有国旗的按钮后。
    • 如果您正在构建一个大型应用程序,并且希望从 WPF、ASP.NET 或其他类库中引用相同的文件,那么我认为这是一个更好的解决方案:stackoverflow.com/a/35813707/2901207跨度>
    【解决方案2】:

    乔什·史密斯为此写了一篇关于他首选方法的深入教程:Creating an Internationalized Wizard in WPF

    这可能会让您进行一次大的重新设计(MVVM solution),但出于其他原因,使用 MVVM 似乎也是值得的。

    【讨论】:

      【解决方案3】:

      我正在使用WPF Localization Extension。在DependencyObjects 上本地化任何类型的DependencyProperty 是一种非常简单的方法。

      • 处于真正的稳定状态
      • 支持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(Normal 和 SP1)
      • 可以在设计时更改所选语言
      • 可以本地化任何类型的数据类型,只要它存在转换器 (TypeConverter)(扩展 LocalizeExtension
      • 内置支持Text、上Text、下TextImages、Brushes、DoubleThickness
      • 不影响任何内存泄漏
      • 保持UID 属性不变
      • 提供SpecificCulture 用作IFormatProvider(例如(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20""123,20"
      • 提供一些功能来检查和获取后台代码中的资源值
      • 不会改变 Thread.CurrentCultureThread.CurrentUICulture 上的文化(可以轻松更改)

      【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2023-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-14
        • 2016-06-04
        相关资源
        最近更新 更多