WPF实现无刷新动态切换多语言(国际化)
1. 在WPF中国际化使用的是 .xaml文件的格式
如图:Resource Dictionary (WPF)
2. 创建默认的语言文件和其他语言文件
这里以英语为默认语言,新建一个 Resource Dictionary (WPF)文件,并命名为DefaultLanguage.xaml,内容如下:
<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="OK"> OK </sys:String> <sys:String x:Key="Cancel"> Cancel </sys:String> </ResourceDictionary>
默认语言文件的 BuildAction要设置为 Page,如图:
为了便于管理,一般将所有的语言文件都放在一个目录下,这里创建lang目录,
然后在创建另一个语言文件,这里是中文,命名为 zh_CN.xaml,内容如下:
<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="OK"> 确定 </sys:String> <sys:String x:Key="Cancel"> 取消 </sys:String> </ResourceDictionary>
其他非默认语言的设置应该如下:
BuildAction设置为:Content ;CopyToOutputDirectory设置为:Copy if newer (先这样做吧,原因未清)
3.在App.xaml中配置默认语言:
<Application x:Class="LanTest.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="lang\DefaultLanguage.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
4.实际使用(敲代码了)
4.1. 界面效果如下:
4.2. 界面的.xaml代码
1 <Window x:Class="LanTest.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Grid> 6 <!--这里的{DynamicResource OK}就是动态调用 资源中的key为OK的内容--> 7 <Button Content="{DynamicResource OK}" HorizontalAlignment="Left" Margin="134,161,0,0" VerticalAlignment="Top" Width="104" Height="38"/> 8 <Button Content="{DynamicResource Cancel}" HorizontalAlignment="Left" Margin="278,161,0,0" VerticalAlignment="Top" Width="100" Height="38"/> 9 <Button Content="Button" HorizontalAlignment="Left" Margin="287,59,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" Loaded="Button_Loaded"/> 10 <ComboBox Name="cbLang" HorizontalAlignment="Left" Margin="118,59,0,0" VerticalAlignment="Top" Width="120"> 11 </ComboBox> 12 13 </Grid> 14 </Window>
4.3. 后台逻辑代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Globalization; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows; 8 using System.Windows.Controls; 9 using System.Windows.Data; 10 using System.Windows.Documents; 11 using System.Windows.Input; 12 using System.Windows.Media; 13 using System.Windows.Media.Imaging; 14 using System.Windows.Navigation; 15 using System.Windows.Shapes; 16 17 namespace LanTest 18 { 19 /// <summary> 20 /// Interaction logic for MainWindow.xaml 21 /// </summary> 22 public partial class MainWindow : Window 23 { 24 public MainWindow() 25 { 26 InitializeComponent(); 27 } 28 29 //定义ComboBox选项的类,存放Name和Value 30 public class CategoryInfo 31 { 32 public string Name 33 { 34 get; 35 set; 36 } 37 public string Value 38 { 39 get; 40 set; 41 } 42 43 } 44 45 //切换语言 46 private void btnChangeLang_Click(object sender, RoutedEventArgs e) 47 { 48 object selectedName = cbLang.SelectedValue; 49 if (selectedName != null) 50 { 51 string langName = selectedName.ToString(); 52 //英语的语言文件名为:DefaultLanguage,所有这里要转换一下 53 if (langName == "en_US") 54 langName = "DefaultLanguage"; 55 //根据本地语言来进行本地化,不过这里上不到 56 //CultureInfo currentCultureInfo = CultureInfo.CurrentCulture; 57 58 ResourceDictionary langRd = null; 59 try 60 { 61 //根据名字载入语言文件 62 langRd = Application.LoadComponent(new Uri(@"lang\" + langName + ".xaml", UriKind.Relative)) as ResourceDictionary; 63 } 64 catch(Exception e2) 65 { 66 MessageBox.Show(e2.Message); 67 } 68 69 if (langRd != null) 70 { 71 //如果已使用其他语言,先清空 72 if (this.Resources.MergedDictionaries.Count > 0) 73 { 74 this.Resources.MergedDictionaries.Clear(); 75 } 76 this.Resources.MergedDictionaries.Add(langRd); 77 } 78 } 79 else 80 MessageBox.Show("Please selected one Language first."); 81 } 82 83 //控件载入时,为ComboBox赋值 84 private void cbLang_Loaded(object sender, RoutedEventArgs e) 85 { 86 List<CategoryInfo> categoryList = new List<CategoryInfo>(); 87 categoryList.Add(new CategoryInfo() { Name = "English", Value = "en_US" }); 88 categoryList.Add(new CategoryInfo() { Name = "中文", Value = "zh_CN" }); 89 90 cbLang.ItemsSource = categoryList;//绑定数据,真正的赋值 91 cbLang.DisplayMemberPath = "Name";//指定显示的内容 92 cbLang.SelectedValuePath = "Value";//指定选中后的能够获取到的内容 93 } 94 } 95 }