【发布时间】:2010-10-23 07:27:48
【问题描述】:
您能否推荐一种为 WPF 应用程序实现多语言系统的好方法?我现在使用的方法涉及 XML、类和 xaml 扩展。它在大多数情况下都可以正常工作,但是当我必须处理动态标签或动态文本时,通常需要一些额外的努力。我想让程序员只在主要问题上工作而忘记了语言问题。
【问题讨论】:
标签: wpf xaml globalization multilingual
您能否推荐一种为 WPF 应用程序实现多语言系统的好方法?我现在使用的方法涉及 XML、类和 xaml 扩展。它在大多数情况下都可以正常工作,但是当我必须处理动态标签或动态文本时,通常需要一些额外的努力。我想让程序员只在主要问题上工作而忘记了语言问题。
【问题讨论】:
标签: wpf xaml globalization multilingual
按照以下步骤操作:
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} 使应用程序在运行时可切换
乔什·史密斯为此写了一篇关于他首选方法的深入教程:Creating an Internationalized Wizard in WPF。
这可能会让您进行一次大的重新设计(MVVM solution),但出于其他原因,使用 MVVM 似乎也是值得的。
【讨论】:
我正在使用WPF Localization Extension。在DependencyObjects 上本地化任何类型的DependencyProperty 是一种非常简单的方法。
Text = {LocText ResAssembly:ResFile:ResKey}等类似绑定的书写风格INotifyPropertyChanged 以供高级使用"this is the '{0}' value"
LocText扩展).resx)(也是运行时动态加载的资源文件)TypeConverter)(扩展 LocalizeExtension)Text、上Text、下Text、Images、Brushes、Double和Thickness
UID 属性不变SpecificCulture 用作IFormatProvider(例如(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20" 或"123,20")Thread.CurrentCulture 或 Thread.CurrentUICulture 上的文化(可以轻松更改)【讨论】:
通过这篇文章,我设法轻松地使用资源文件来处理多语言 WPF 窗口。 http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx 您应该检查一下,因为它非常简单有效。
【讨论】: