这是整个代码流的概述。
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。
现在,提交,应用等UI标签已经通过resx文件进行了本地化。
我的问题是什么是将formatcode.xml中的值本地化为英语,德语,中文等的最佳方法。
频带1 BAND2
我看到的样本主要涉及本地化ui相关标签和内容。虽然我们在这种情况下部分地处理ui,但它的价值来自必须本地化的业务流程。
答案 0 :(得分:0)
您是否尝试过使用绑定转换器?这是我使用的内容,以及执行实际翻译的Translate字符串扩展器。
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。选择器只是一个对话框,用于向用户显示选项列表。实现这一点是微不足道的,不包括在内。 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;
}
}