在xml标记中本地化值
本文关键字:本地化 xml | 更新日期: 2023-09-27 18:22:02
这是对整个代码流的概述。
FormatCode.xml是具有这种格式的输入文件之一。
<FormatCode id="405">
<Map>
<enumvalue>0</enumvalue>
<actualvalue>Off</actualvalue>
</Map>
<Map>
<enumvalue>1</enumvalue>
<actualvalue>Band1</actualvalue>
</Map>
<Map>
<enumvalue>2</enumvalue>
<actualvalue>Band2</actualvalue>
</Map>
<Map>
<enumvalue>3</enumvalue>
<actualvalue>Band3</actualvalue>
</Map>
</FormatCode>
我的应用程序将该xml文件中的值读取到模型中的以下CLR对象中。其他xml文件也用作类中某些字段的输入,但我们不必担心。
public class parameter
{
public string ParameterName
{
get;
set;
}
public string Enumvalue
{
get;
set;
}
public string CurrentValue
{
get;
set;
}
}
这通常通过视图模型进入xaml。
<TextBlock x:Name="FnNameLbl" Text="{Binding Path=ParameterName}" >
<ComboBox ItemSource="{binding protset}" displaymemeberpath="{binding path=current Value}">
protset是ObservableCollection。
现在,像submit、apply这样的UI标签已经通过resx文件进行了本地化。
我的问题是,将formatcode.xml中的值本地化为英语、德语、中文等等的最佳方式是什么
频带1波段2
我看到的示例主要处理与ui相关的标签和内容的本地化。尽管在这种情况下,我们在一定程度上处理ui,但它的价值来自于必须本地化的业务流程。
您尝试过使用绑定转换器吗?以下是我使用的内容,以及执行实际翻译的翻译字符串扩展程序。
public class LocalizeConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
return ((string)value).Translate(culture);
}
return null;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
return (string)value;
}
return null;
}
}
我在下面包含了使用xml文件进行本地化的代码。您甚至可以交互式地更新xml。Chooser只是一个对话框,我们用来向用户显示一个选项列表。它的实现是琐碎的,而且不包括在内。TextEntry与此类似,它是一个接受用户输入的对话框。
在我的基本窗口类中,我添加了一个TextInput侦听器来捕获CTRL+T(更新翻译xml)或CTRL+I(交互式)。
window.TextInput += (sender, args) =>
{
if (args.ControlText == "'x14") // Ctrl+T
{
"".Translate(true);
}
if (args.ControlText == "'x09") // Ctrl+I
{
"".Translate(true, true);
}
};
public static class LocalExtensions
{
private static Dictionary<string,SortedDictionary<string,string>> languages = new Dictionary<string,SortedDictionary<string,string>>(5);
private static bool autoAdd;
public static bool interactiveAdd;
public static string Translate(this String phrase, bool autoAdd, bool interactive = false)
{
var cultures = CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures);
var chooser = new Chooser(Application.Current.Windows[0], "Translate from English To:", cultures.Select(culture => culture.EnglishName));
chooser.ShowDialog();
var selectedCulture = cultures.First(candidate => candidate.EnglishName == chooser.selectedItem);
Localize.SetDefaultCulture(selectedCulture);
LocalExtensions.autoAdd = autoAdd;
LocalExtensions.interactiveAdd = interactive;
return phrase.Translate();
}
public static string Translate(this String phrase)
{
return phrase.Translate(CultureInfo.CurrentCulture);
}
public static string Translate(this String phrase, CultureInfo culture) {
if (String.IsNullOrWhiteSpace(phrase)) return phrase;
var lang = culture.TwoLetterISOLanguageName;
SortedDictionary<string,string> translations;
if (!Directory.Exists(@"Languages"))
{
return phrase;
}
var pathName = FindFile("Languages''" + lang + ".xml");
if ( !languages.ContainsKey(lang) ) {
try {
var xaml = File.ReadAllText(pathName, Encoding.UTF8);
translations = (SortedDictionary<string, string>)XamlServices.Parse(xaml);
} catch(Exception) {
translations = new SortedDictionary<string,string>();
}
languages.Add(lang,translations);
} else {
translations = languages[lang];
}
if (translations.ContainsKey(phrase))
{
// return the translation for the specified phrase
var tran = translations[phrase];
var result = InteractiveUpdate(phrase, tran);
if ( result != tran ) {
translations[phrase] = result;
SaveChanges(translations,pathName);
}
return translations[phrase];
}
// HACK: This is enabled by pressing CTRL+T on any window in the App.
// Please note that any phrases in that window will not be translated
// only phrases loaded in subsequent windows.
if (LocalExtensions.autoAdd)
{
var result = InteractiveUpdate(phrase,phrase);
translations.Add(phrase, result);
SaveChanges(translations, pathName);
}
return phrase;
}
private static void SaveChanges(SortedDictionary<string,string> translations, string pathName)
{
var writer = new StreamWriter(pathName, false, Encoding.UTF8);
XamlServices.Save(writer, translations);
writer.Close();
}
private static string InteractiveUpdate(String phrase, String tran)
{
// HACK: Interactive update will be enabled by pressing CTRL+I on any window.
// The same caveat applies here as with autoAdd above.
if (interactiveAdd && !phrase.StartsWith("pack:"))
{
interactiveAdd = autoAdd = false;
var tb = new TextBox
{
TextWrapping = TextWrapping.Wrap,
AcceptsReturn = true,
Height = double.NaN,
Width = double.NaN,
Text = tran
};
var te = new TextEntry(Application.Current.Windows[0],"Please translate:",tb,TextEntryType.AlphaNumeric);
te.blurEnabled = false;
te.ShowDialog();
tran = tb.Text;
interactiveAdd = autoAdd = true;
}
return tran;
}
private static string FindFile(string fileName)
{
var candidatePath = fileName;
if (!File.Exists(fileName))
{
candidatePath = AppDomain.CurrentDomain.BaseDirectory + "''" + fileName;
if (!File.Exists(candidatePath) && ApplicationDeployment.IsNetworkDeployed)
{
candidatePath = ApplicationDeployment.CurrentDeployment.DataDirectory + "''" + fileName;
}
}
return candidatePath;
}
}