Благодаря намеку Феликса я реализовал решение Tomer Shamam . Это решение позволяет менять язык во время выполнения. Далее выбранный язык используется во всех открытых окнах проекта WPF. Вы можете просмотреть мой тестовый проект на GitHub .
Я работаю с VS 2015 в приложении WPF-test для нового проекта, в котором пользователь может изменить язык во время выполнения.
Поэтому я сделал свой тестовый проект в соответствии с этой статьей .
Я добавил три RESX-файла в папку Proerties.
Затем я добавил конструктор и методы переключения между языками.
namespace MultipleLanguages
{
/// <summary>
/// Interaktionslogik fur "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);
}
}
}
Наконец я реализовал ресурсы в моем окне 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>
И 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();
}
}
После запуска язык по умолчанию является немецким.
Когда я переключаюсь на английский, текущая культура потока изменяется, но я не вижу никаких изменений в графическом интерфейсе.
Но когда я нажимаю кнопку «Тест», я получаю английские значения из ресурсов.
Наконец я попытался обновить окно, UpdateLayout
но ничего не произошло.
Большой вопрос: как я могу обновить окно во время выполнения?
PS: Используя XAML вместо RESX, это не было проблемой (кроме сообщений об ошибках от проверки).