我有多种语言的多语言应用程序。在我的应用程序中有用户可以更改的文本,但默认文本也需要翻译成不同的语言。这意味着如果用户想要编辑某些文本,则需要为他的语言编辑resx文件。
首先我尝试使用ResourceWriter
类,然后我的resx文件被破坏了。我又创造了。
其次我尝试使用ResXResourceWriter
课程,但我找不到能给我这个功能的好方法(编辑某些属性的值)。
我认为只需阅读像xml这样的resx文件并进行编辑,但我不知道如何再次构建应用程序。
是否可以在运行时从应用程序编辑resx中的值。之后就可以使用c#代码构建应用程序,就像在visual studio中构建一样。
编辑我不想将resx文件从 .en.resx更改为其他方面( .de.resx)。我想更改此resx文件中的值。例如,我有一个关键是btnCont值为Click。我想改变btnCont以获得新价值点击我,例如。然后再次生成更改的resx文件的dll。
感谢您的建议
答案 0 :(得分:0)
也许有更好的方法可以做到这一点(我很想了解它们),但是当我需要在运行时更改语言时,我所做的就是将所有可本地化的字符串作为readonly属性添加到我的viewmodel。
public string ImportString { get { return lang.Import; } }
然后我只是从XAML添加一个绑定到这个字符串,并在更改UI文化后,我在我的viewmodel的所有字符串属性上调用OnPropertyChanged。
protected void NotifyAllPropertiesChanged<T>()
{
foreach (var p in this.GetType().GetProperties())
if (p.PropertyType == typeof(T))
OnPropertyChanged(p.Name);
}
答案 1 :(得分:0)
尝试编译以下代码
<Window x:Class="WPFLocalizationSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel HorizontalAlignment="Left" Margin="20" VerticalAlignment="Top">
<TextBlock Text="{DynamicResource tbName}" Margin="2" />
<TextBox Width="200" Margin="2"/>
<Button Content="{DynamicResource btnAdd}" HorizontalAlignment="Left" Margin="2" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Margin="20,181,0,0" VerticalAlignment="Top" Orientation="Vertical" Width="305">
<TextBlock Text="Translation Panel" FontSize="20" FontWeight="Black" />
<Grid >
<TextBlock Text="{DynamicResource tbName}" Margin="2" />
<TextBox Width="200" Margin="2" HorizontalAlignment="Right" Tag="tbName" x:Name="tbNameLoc"/>
</Grid>
<Grid>
<TextBlock Text="{DynamicResource btnAdd}" Margin="2" />
<TextBox Width="200" Margin="2" HorizontalAlignment="Right" Tag="btnAdd" x:Name="btnAddLoc" />
</Grid>
<Button Content="Translate/Update" HorizontalAlignment="Left" Margin="2" Click="Button_Click" />
</StackPanel>
</Grid>
</Window>
这是MainWindow.Xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace WPFLocalizationSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private static ResourceDictionary CurrentLanguageDictionary;
private static string LanguageResourceFile = "en-US.xaml";
private Dictionary<string, System.Windows.Controls.TextBox> TextBoxControls = new Dictionary<string, TextBox>();
public MainWindow()
{
InitializeComponent();
AddControlsToLocalization();
}
private void AddControlsToLocalization()
{
TextBoxControls.Add("tbName", tbNameLoc);
TextBoxControls.Add("btnAdd", btnAddLoc);
}
public static bool SaveLanguageFile(Dictionary<string, System.Windows.Controls.TextBox> TextBoxControls, string selectedLang)
{
bool status = false;
try
{
using (var fs = new FileStream(LanguageResourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// Read in ResourceDictionary File
CurrentLanguageDictionary = (ResourceDictionary)XamlReader.Load(fs);
}
foreach (string key in TextBoxControls.Keys)
{
TextBox txt = TextBoxControls[key];
if (txt.Text.Length > 0)
{
CurrentLanguageDictionary[key] = txt.Text;
}
}
using (var writer = new StreamWriter(LanguageResourceFile))
{
XamlWriter.Save(CurrentLanguageDictionary, writer);
}
status = true;
}
catch (Exception _exception)
{
MessageBox.Show("Exception in language file edit");
return false;
}
SetLanguageResourceDictionary(LanguageResourceFile, App.Current);
return status;
}
public static void SetLanguageResourceDictionary(String inFile, Application application)
{
if (File.Exists(inFile))
{
// Read in ResourceDictionary File
var languageDictionary = new ResourceDictionary();
languageDictionary.Source = new Uri(inFile,UriKind.Relative);
// Remove any previous Localization dictionaries loaded
int langDictId = -1;
for (int i = 0; i < application.Resources.MergedDictionaries.Count; i++)
{
var md = application.Resources.MergedDictionaries[i];
// Make sure your Localization ResourceDictionarys have the ResourceDictionaryName
// key and that it is set to a value starting with "Loc-".
if (md.Contains("ResourceDictionaryName"))
{
if (md["ResourceDictionaryName"].ToString().Equals("en-US"))
{
langDictId = i;
break;
}
}
}
if (langDictId == -1)
{
// Add in newly loaded Resource Dictionary
application.Resources.MergedDictionaries.Add(languageDictionary);
}
else
{
// Replace the current langage dictionary with the new one
application.Resources.MergedDictionaries[langDictId] = languageDictionary;
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SaveLanguageFile(TextBoxControls, "en-US");
}
}
}
以下是en-US.xaml示例(资源字典文件)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<sys:String x:Key="ResourceDictionaryName">en-US</sys:String>
<sys:String x:Key="tbName">Enter youe Name</sys:String>
<sys:String x:Key="btnAdd">Add</sys:String>
</ResourceDictionary>
在app.xaml中添加资源文件
<Application x:Class="WPFLocalizationSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="en-US.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
如果你编译它,你会看到一个带有两个样本控件的表单。 下面翻译面板补充说。您可以键入要更改的任何文本 点击翻译按钮更改的文本将在en-US文件中更新。 如果你想保存不同的文件也可以。
注意:en-US.xaml文件应该在release文件夹中。