前段时候写了一个WPF多语言界面处理,个人感觉还行,分享给大家.使用合并字典,静态绑定,动态绑定.样式等东西
效果图
定义一个实体类LanguageModel,实际INotifyPropertyChanged接口
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ComponentModel; 6 7 namespace WpfApplication1 8 { 9 public class LanguageModel : INotifyPropertyChanged 10 { 11 private string _languageCode; 12 private string _languageName; 13 private string _languageDisplayName; 14 private string _resourcefile; 15 private bool _languageenabled; 16 /// <summary> 17 /// 语言代码 如en,zh 18 /// </summary> 19 public string LanguageCode 20 { 21 get { return _languageCode; } 22 set { _languageCode = value; OnPropertyChanged("LanguageCode"); } 23 } 24 /// <summary> 25 /// 语言名称 如:中国 ,English 26 /// </summary> 27 public string LanguageName 28 { 29 get { return _languageName; } 30 set { _languageName = value; OnPropertyChanged("LanguageName"); } 31 } 32 /// <summary> 33 /// 语言名称 如:中国 ,English 34 /// </summary> 35 public string LanguageDisplayName 36 { 37 get { return _languageDisplayName; } 38 set { _languageDisplayName = value; OnPropertyChanged("LanguageDisplayName"); } 39 } 40 41 /// <summary> 42 /// 语言资源文件地址 43 /// </summary> 44 public string Resourcefile 45 { 46 get { return _resourcefile; } 47 set { _resourcefile = value; OnPropertyChanged("Resourcefile"); } 48 } 49 50 /// <summary> 51 /// 是否启用此语言配置文件 52 /// </summary> 53 public bool LanguageEnabled 54 { 55 get { return _languageenabled; } 56 set { _languageenabled = value; OnPropertyChanged("LanguageEnabled"); } 57 } 58 59 protected void OnPropertyChanged(string name) 60 { 61 PropertyChangedEventHandler handler = PropertyChanged; 62 if (handler != null) 63 { 64 handler(this, new PropertyChangedEventArgs(name)); 65 } 66 } 67 68 public event PropertyChangedEventHandler PropertyChanged; 69 } 70 }
核心类 I18N
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows; 6 using System.IO; 7 8 9 10 namespace WpfApplication1 11 { 12 public class Language : LanguageModel 13 { 14 private ResourceDictionary _resource; 15 16 public ResourceDictionary Resource 17 { 18 get { return _resource; } 19 set { _resource = value; OnPropertyChanged("Resource"); } 20 } 21 } 22 23 24 /// <summary> 25 /// 国际化 注:语言资源文件在VS2010的属性设置 复制到输出目录:始终复制 生成操作:内容 26 /// 资源文件 LanguageCode ,LanguageName, LanguageDisplayName,LanguageEnabled 字段必填 27 /// </summary> 28 public class I18N 29 { 30 private static string _currentLanguage = "zh-cn"; 31 /// <summary> 32 /// 设置或获取语言编码,如果设置失败,则可能语言资源文件错误 33 /// </summary> 34 public static string CurrentLanguage 35 { 36 get { return _currentLanguage; } 37 set 38 { 39 if(UpdateCurrentLanguage(value)) 40 _currentLanguage = value; 41 } 42 } 43 44 private static List<Language> _languageIndex; 45 /// <summary> 46 /// 所有语言索引 47 /// </summary> 48 public static List<Language> LanguageIndex 49 { 50 get { return _languageIndex; } 51 } 52 53 /// <summary> 54 /// 初始化,加载语言目录下的所有语言文件 55 /// </summary> 56 public static void Initialize() 57 { 58 _languageIndex = new List<Language>(); 59 string dirstring = AppDomain.CurrentDomain.BaseDirectory + "Resource\Language\"; 60 DirectoryInfo directory = new DirectoryInfo(dirstring); 61 FileInfo[] files = directory.GetFiles(); 62 foreach (var item in files) 63 { 64 Language language = new Language(); 65 ResourceDictionary rd = new ResourceDictionary(); 66 rd.Source = new Uri(item.FullName); 67 language.LanguageCode = rd["LanguageCode"] == null ? "未知" : rd["LanguageCode"].ToString(); 68 language.LanguageName = rd["LanguageName"] == null ? "未知" : rd["LanguageName"].ToString(); 69 language.LanguageDisplayName = rd["LanguageDisplayName"] == null ? "未知" : rd["LanguageDisplayName"].ToString(); 70 language.LanguageEnabled = rd["LanguageEnabled"] == null ? false : bool.Parse(rd["LanguageEnabled"].ToString()); 71 language.Resourcefile = item.FullName; 72 language.Resource = rd; 73 if(language.LanguageEnabled) 74 _languageIndex.Add(language); 75 } 76 } 77 78 /// <summary> 79 /// 更新语言配置. 同时同步CurrentLanguage字段 80 /// </summary> 81 private static bool UpdateCurrentLanguage(string LanguageCode) 82 { 83 if (LanguageIndex.Exists(P => P.LanguageCode == LanguageCode&&P.LanguageEnabled==true)) 84 { 85 Language language = LanguageIndex.Find(P => P.LanguageCode == LanguageCode&&P.LanguageEnabled==true); 86 if (language != null) 87 { 88 foreach (var item in LanguageIndex) 89 { 90 Application.Current.Resources.MergedDictionaries.Remove(item.Resource); 91 } 92 Application.Current.Resources.MergedDictionaries.Add(language.Resource); 93 return true; 94 } 95 } 96 return false; 97 } 98 99 /// <summary> 100 /// 查找语言资源文件具体的某项值,类似索引器 101 /// </summary> 102 /// <param name="key"></param> 103 /// <returns></returns> 104 public static string GetLanguageValue(string key) 105 { 106 ResourceDictionary rd = Application.Current.Resources; 107 if (rd == null) 108 return ""; 109 object obj = rd[key]; 110 return obj == null ? "" : obj.ToString(); 111 } 112 113 } 114 }
资料文件直接使用 XX.xaml文件 注:语言资源文件在VS2010的属性设置 复制到输出目录:始终复制 生成操作:内容 ,确保xaml文件会复制到项目中,而不是编译到dll中
1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 3 xmlns:sys="clr-namespace:System;assembly=mscorlib"> 4 <sys:String x:Key="LanguageCode">zh</sys:String> 5 <sys:String x:Key="LanguageName">简休中文</sys:String> 6 <sys:String x:Key="LanguageDisplayName">简休中文</sys:String> 7 <sys:String x:Key="LanguageEnabled">true</sys:String> 8 9 10 11 <sys:String x:Key="LanguageLanguage">语言:</sys:String> 12 <sys:String x:Key="LanguageA">字段A:</sys:String> 13 <sys:String x:Key="LanguageB">字段B:</sys:String> 14 <sys:String x:Key="LanguageC">字段C:</sys:String> 15 16 17 </ResourceDictionary>
默认语言可以在App.xaml里设置
1 <Application x:Class="WpfApplication1.App" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Startup="Application_Startup" 5 StartupUri="MainWindow.xaml"> 6 <Application.Resources> 7 <ResourceDictionary> 8 <ResourceDictionary.MergedDictionaries> 9 <ResourceDictionary Source="Resource/Language/zh.xaml"/> 10 </ResourceDictionary.MergedDictionaries> 11 </ResourceDictionary> 12 </Application.Resources> 13 </Application>
界面上使用动态绑定或静态绑定资源 (DynamicResource ,StaticResource) , DataGrid表头使用HeaderSytle
动态绑定:可以实时更新语言种类.
静态绑定,不能实时更新语言种类,如:在登录的时候已经确实语言种类,进入系统后而不能更改.
示例效果界面
1 <Window x:Class="WpfApplication1.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 <Window.Resources> 6 <Style x:Key="HeaderA" TargetType="{x:Type DataGridColumnHeader}"> 7 <Setter Property="Content" Value="{DynamicResource LanguageA}" /> 8 </Style> 9 <Style x:Key="HeaderB" TargetType="{x:Type DataGridColumnHeader}"> 10 <Setter Property="Content" Value="{DynamicResource LanguageB}" /> 11 </Style> 12 <Style x:Key="HeaderC" TargetType="{x:Type DataGridColumnHeader}"> 13 <Setter Property="Content" Value="{DynamicResource LanguageC}" /> 14 </Style> 15 </Window.Resources> 16 <Grid> 17 <Grid.RowDefinitions> 18 <RowDefinition Height="40*" /> 19 <RowDefinition Height="271*" /> 20 </Grid.RowDefinitions> 21 <Label Content="{DynamicResource LanguageLanguage}" Height="28" HorizontalAlignment="Left" Margin="26,12,0,0" Name="label1" VerticalAlignment="Top" /> 22 <ComboBox Height="23" HorizontalAlignment="Left" DisplayMemberPath="LanguageDisplayName" SelectedIndex="0" Margin="160,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="204" SelectionChanged="comboBox1_SelectionChanged" /> 23 <DataGrid AutoGenerateColumns="False" Grid.Row="1" Height="188" HorizontalAlignment="Left" Margin="12,17,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="352" > 24 <DataGrid.Columns> 25 <DataGridTemplateColumn Width="50" HeaderStyle="{StaticResource HeaderA}" > 26 <DataGridTemplateColumn.CellTemplate> 27 <DataTemplate> 28 <CheckBox Name="chkStart" IsChecked="{Binding IsStart,UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=DataContext.IsEnabled, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/> 29 </DataTemplate> 30 </DataGridTemplateColumn.CellTemplate> 31 </DataGridTemplateColumn> 32 <DataGridTextColumn Width="3*" HeaderStyle="{StaticResource HeaderB}" Binding="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" /> 33 <DataGridTextColumn Width="3*" HeaderStyle="{StaticResource HeaderC}" Binding="{Binding Path=Website, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors =True}" IsReadOnly="True" /> 34 35 </DataGrid.Columns> 36 </DataGrid> 37 38 </Grid> 39 </Window>
最后附上源代码 ,谢谢
End
技术在于分享,大家共同进步