目前,我正在尝试创建在运行时支持语言切换的应用程序。我找到了一个教程,建议使用Resource Dictionaries
来实现此目的。建议的方法适用于XAML中具有其内容集的元素,例如,如下<Button Content="{DynamicResource MainTitle}"
。
问题是我的MenuItem
设置为绑定到Header
Text
的{{1}},Command
不会改变Header
到CurrentUICulture
。它仍然是相同的,或者,我应该说,正确的项目的默认语言,虽然我正在改变语言切换。代表支持的语言的MenuItems
也是如此。
这是我正在使用的代码。
App.xaml.cs
public partial class App : Application
{
private static String prefix = "Resources/lang.";
public static event EventHandler LanguageChanged;
private static List<CultureInfo> m_Languages = new List<CultureInfo>();
public static List<CultureInfo> Languages
{
get
{
return m_Languages;
}
}
public static CultureInfo Language
{
get
{
return System.Threading.Thread.CurrentThread.CurrentUICulture;
}
set
{
if (value == null) throw new ArgumentNullException("value");
if (value == System.Threading.Thread.CurrentThread.CurrentUICulture) return;
System.Threading.Thread.CurrentThread.CurrentUICulture = value;
ResourceDictionary dictionary = new ResourceDictionary();
dictionary.Source = new Uri(String.Format(prefix+ "{0}.xaml", value.Name), UriKind.Relative);
ResourceDictionary oldDictionary = (from d in Current.Resources.MergedDictionaries
where d.Source != null &&
d.Source.OriginalString.StartsWith(prefix)
select d).First();
if (oldDictionary != null)
{
int index = Current.Resources.MergedDictionaries.IndexOf(oldDictionary);
Current.Resources.MergedDictionaries.Remove(oldDictionary);
Current.Resources.MergedDictionaries.Insert(index, dictionary);
}
else
{
Current.Resources.MergedDictionaries.Add(dictionary);
}
LanguageChanged(Current, new EventArgs());
}
}
public App()
{
InitializeComponent();
App.LanguageChanged += App_LanguageChanged;
m_Languages.Clear();
m_Languages.Add(new CultureInfo("en"));
m_Languages.Add(new CultureInfo("ru-RU"));
Language = WpfTestProject.Properties.Settings.Default.DefaultLanguage;
}
public void App_LanguageChanged(Object sender, EventArgs e)
{
WpfTestProject.Properties.Settings.Default.DefaultLanguage = Language;
WpfTestProject.Properties.Settings.Default.Save();
}
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
App.LanguageChanged += LanguageChanged;
SetLanguageMenu();
}
private void SetLanguageMenu()
{
CultureInfo currLang = App.Language;
LangMenu.Items.Clear();
foreach (var lang in App.Languages)
{
MenuItem menuLang = new MenuItem();
Debug.WriteLine("Here is a display name: " + lang.DisplayName);
menuLang.Header = lang.DisplayName;
menuLang.Tag = lang;
menuLang.IsChecked = lang.Equals(currLang);
menuLang.Click += ChangeLanguageClick;
LangMenu.Items.Add(menuLang);
}
}
private void LanguageChanged(Object sender, EventArgs e)
{
//I've tried resseting LanguageMenu from here - no effect
CultureInfo currLang = App.Language;
foreach (MenuItem i in LangMenu.Items)
{
CultureInfo ci = i.Tag as CultureInfo;
i.IsChecked = ci != null && ci.Equals(currLang);
}
}
private void ChangeLanguageClick(Object sender, EventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
CultureInfo lang = mi.Tag as CultureInfo;
if (lang != null)
{
App.Language = lang;
SetLanguageMenu();
}
}
}
}
MainWindow.xaml
<Window x:Class="WpfTestProject.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:WpfTestProject"
mc:Ignorable="d"
Title="{DynamicResource MainTitle}" Height="600" Width="800">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New" Executed="NewCommand_Executed"/>
<CommandBinding Command="ApplicationCommands.Open" Executed="OpenCommand_Executed"/>
<CommandBinding Command="ApplicationCommands.Save" Executed="SaveCommand_Executed"/>
<CommandBinding Command="ApplicationCommands.SaveAs" Executed="SaveAsCommand_Executed"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="N" Modifiers="Ctrl" Command="{Binding ApplicationCommands.New}"/>
<KeyBinding Key="O" Modifiers="Ctrl" Command="{Binding ApplicationCommands.Open}"/>
<KeyBinding Key="S" Modifiers="Ctrl" Command="{Binding ApplicationCommands.Save}"/>
<KeyBinding Key="S" Modifiers="Ctrl+Shift" Command="{Binding ApplicationCommands.SaveAs}"/>
</Window.InputBindings>
<DockPanel Name="DockPanel" HorizontalAlignment="Stretch" LastChildFill="False" VerticalAlignment="Stretch">
<MenuItem Command="ApplicationCommands.Open" Header="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Command.Text}"/>
<MenuItem Name="LangMenu" Header="Languages" HorizontalAlignment="Right"/>
</DockPanel>
</Window>
更新
英语资源字典
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestProject.Properties"
xmlns:v="clr-namespace:System;assembly=mscorlib">
<v:String x:Key="MainTitle">Title</v:String>
的App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="WpfTestProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<userSettings>
<WpfTestProject.Properties.Settings>
<setting name="DefaultLanguage" serializeAs="String">
<value>en</value>
</setting>
</WpfTestProject.Properties.Settings>
</userSettings>
关于我做错了什么的任何想法?
答案 0 :(得分:1)
问题是我的MenuItem,它的标题设置为绑定到它的文本命令,不会根据CurrentUICulture更改标题。
当然不是,为什么会这样?
您应该像设置其他元素的本地化文本一样设置Header
的{{1}}:
MenuItem
显然,您必须执行此操作才能使本地化工作在<MenuItem Command="ApplicationCommands.Open" Header="{DynamicResource OpenText}"/>
元素之间。