我正在使用 VS 2015 开发一个新项目的 WPF 测试应用程序,用户可以在该项目中在运行时更改语言。
所以我根据这篇文章做了我的测试项目。
我在 Proerties 文件夹中添加了三个 RESX 文件。
然后我添加了一个构造函数和用于在语言之间切换的方法。
namespace MultipleLanguages
{
/// <summary>
/// Interaktionslogik für "App.xaml"
/// </summary>
public partial class App : Application
{
/// <summary>
/// The constructor.
/// </summary>
public App()
{
// Sets the desired language.
ChangeLanguage("de-DE");
}
/// <summary>
/// Switches to language german.
/// </summary>
public void SwitchToLanguageGerman()
{
ChangeLanguage("de-DE");
}
/// <summary>
/// Switches to language english.
/// </summary>
public void SwitchToLanguageEnglish()
{
ChangeLanguage("en-US");
}
/// <summary>
/// Changes the language according to the given culture.
/// </summary>
/// <param name="culture">The culture.</param>
private void ChangeLanguage(string culture)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
MultipleLanguages.Properties.Resources.Culture = new CultureInfo(culture);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我将资源实现到我的 WPF 窗口。
首先是 XAML:
<Window x:Class="MultipleLanguages.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MultipleLanguages"
xmlns:mlres="clr-namespace:MultipleLanguages.Properties"
mc:Ignorable="d"
Title="{x:Static mlres:Resources.mainwindowtitle}"
Height="350"
Width="525">
<Grid x:Name="grd_mainpanel">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid x:Name="grd_persondatapanel"
Grid.Row="0"
Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Content="{x:Static mlres:Resources.firstname}"
Margin="5"></Label>
<Label Grid.Row="1"
Grid.Column="0"
Content="{x:Static mlres:Resources.lastname}"
Margin="5"></Label>
</Grid>
<WrapPanel x:Name="wrp_buttonpanel"
Grid.Row="1"
Grid.Column="0">
<!--Test to get values from the resources-->
<Button x:Name="btn_testresource"
Margin="5"
Click="btn_testresource_Click">Test</Button>
<!--Switch to language german-->
<Button x:Name="btn_switchtogerman"
Margin="5"
Click="btn_switchtogerman_Click"
Content="{x:Static mlres:Resources.switchtogerman}"></Button>
<!--Switch to language english-->
<Button x:Name="btn_switchtoenglish"
Margin="5"
Click="btn_switchtoenglish_Click"
Content="{x:Static mlres:Resources.switchtoenglish}"></Button>
</WrapPanel>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
和 C# 代码:
public partial class MainWindow : Window
{
/// <summary>
/// The constructor.
/// </summary>
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// For testing the resource dictionaries.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_testresource_Click(object sender, RoutedEventArgs e)
{
// Shows the name of the current culture.
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture;
MessageBox.Show("The name of the current culture is '" + ci.Name + "'");
////// Shows the text to the resource key "firstname" according to the current culture.
////ResourceManager rm1 = new ResourceManager("MultipleLanguages.TextResource1", System.Reflection.Assembly.GetExecutingAssembly());
////MessageBox.Show("'firstname' aus MultipleLanguages.TextResource1" + rm1.GetString("firstname"));
////ResourceManager rm2 = new ResourceManager("MultipleLanguages.TextResources.TextResource2", System.Reflection.Assembly.GetExecutingAssembly());
////MessageBox.Show("'firstname' aus MultipleLanguages.TextResources.TextResource2" + rm2.GetString("firstname"));
// Shows values to the given names from the resource - according to the current culture, which was set in App.xaml.cs.
ResourceManager rm = MultipleLanguages.Properties.Resources.ResourceManager;
MessageBox.Show("firstname : " + rm.GetString("firstname"));
MessageBox.Show("lastname : " + rm.GetString("lastname"));
}
private void btn_switchtogerman_Click(object sender, RoutedEventArgs e)
{
((App)Application.Current).SwitchToLanguageGerman();
UpdateLayout();
}
private void btn_switchtoenglish_Click(object sender, RoutedEventArgs e)
{
((App)Application.Current).SwitchToLanguageEnglish();
UpdateLayout();
}
}
Run Code Online (Sandbox Code Playgroud)
启动后默认语言为德语。
当我切换到英语时,线程的当前文化发生了变化,但我在 GUI 中没有看到任何变化。
但是当我单击“测试”按钮时,我从资源中获取了英文值。
最后我尝试刷新窗口,UpdateLayout但什么也没发生。
大问题:如何在运行时刷新窗口?
PS:通过使用 XAML 而不是 RESX,这没有问题(除了来自验证的错误消息)。
小智 0
我建议使用 ResourceDictionaries 而不是 .resx 文件。在绑定上只需使用 DynamicResource。当您加载另一个 ResourceDictionary 时,文本将自动更新。只需按照以下步骤操作:
// On app start load some language dictionary (German in this case)
Uri uri = new Uri("Resources/German.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
ResourceDictionary myResourceDictionary =
(ResourceDictionary)reader.LoadAsync(info.Stream);
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary);
...
//Now switch to another language (English in this case) on some button click or similar...
Application.Current.Resources.MergedDictionaries.Clear();
Uri uri = new Uri("Resources/English.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
ResourceDictionary myResourceDictionary =
(ResourceDictionary)reader.LoadAsync(info.Stream);
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary);
...
Your texts shall be bound like this:
<TextBlock
Text="{DynamicResource myResourceText}" />
Run Code Online (Sandbox Code Playgroud)
English.xml ResourceDictionary 的内容应如下所示:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="myStringNr1">Start</sys:String>
<sys:String x:Key="myStringNr2">Stop</sys:String>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
您的 German.xml ResourceDictionary 可能如下所示:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="myStringNr1">Starten</sys:String>
<sys:String x:Key="myStringNr2">Stoppen</sys:String>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
如果您的字典位于另一个程序集中,则像这样定位它们:
var myDictionary= new Uri("pack://sourceassembly:,,,/resources/English.xaml", UriKind.RelativeOrAbsolute);
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = myDictionary});
Run Code Online (Sandbox Code Playgroud)
如果您对这种方法有疑问,请随时发表评论,我将尝试扩展我的答案。此致。
| 归档时间: |
|
| 查看次数: |
5229 次 |
| 最近记录: |