WPF-实现多语言的静态(需重启)与动态切换(不消重启) ...

打印 上一主题 下一主题

主题 846|帖子 846|积分 2538

目次
一、多语言切换(需重启)
1、配置文件添加Key
2、新增附加属性当前选择语言
3、创建资源文件
 4、初始化多语言聚集
5、切换多语言并更新配置文件
6、应用程序启动根据配置切换多语言
 7、使用
二、多语言切换(无需重启)
1、创建多语言标志扩展基类
2、添加资源转换器
3、创建资源文件
4、继续基类创建指定资源文件扩展
5、添加资源文件管理
6、切换语言
7、使用
8、后台使用多语言
①获取多语言资源字符串
②后台绑定



一、多语言切换(需重启)

1、配置文件添加Key

  1.         <appSettings>
  2.                 <add key="language" value="zh-CN"/>
  3.         </appSettings>
复制代码
2、新增附加属性当前选择语言

  1.         public CultureInfo SelectLanguage
  2.         {
  3.             get => (CultureInfo)GetValue(SelectLanguageProperty);
  4.             set => SetValue(SelectLanguageProperty, value);
  5.         }
  6.         public static readonly DependencyProperty SelectLanguageProperty =
  7.             DependencyProperty.Register("SelectLanguage", typeof(CultureInfo), typeof(MainWindow));
复制代码
3、创建资源文件


 4、初始化多语言聚集

  1.         public ObservableCollection<CultureInfo> CultureInfos { get; private set; } = new ObservableCollection<CultureInfo>();
  2.         private void Window_Loaded(object sender, RoutedEventArgs e)
  3.         {
  4.             var dir =Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
  5.             var curs = CultureInfo.GetCultures(CultureTypes.AllCultures);
  6.             foreach (CultureInfo cur in curs)
  7.             {
  8.                 if (string.IsNullOrWhiteSpace(cur.Name)) continue;
  9.                 string landir = Path.Combine(dir, cur.Name);
  10.                 if (Directory.Exists(landir)) CultureInfos.Add(cur);
  11.             }
  12.             if (CultureInfos.Any(cur => cur.Name.Equals("zh-CN", StringComparison.OrdinalIgnoreCase)) is false)
  13.             {
  14.                 var cur = curs.FirstOrDefault(c => c.Name.Equals("zh-CN", StringComparison.OrdinalIgnoreCase));
  15.                 if (cur != null) CultureInfos.Add(cur);
  16.             }
  17.             SelectLanguage = Thread.CurrentThread.CurrentCulture;
  18.         }
复制代码
5、切换多语言并更新配置文件

  1.         protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  2.         {
  3.             base.OnPropertyChanged(e);
  4.             if (e.Property == SelectLanguageProperty)
  5.             {
  6.                 if (SelectLanguage == Thread.CurrentThread.CurrentCulture) return;
  7.                 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  8.                 if (ConfigurationManager.AppSettings["language"] is null)
  9.                     config.AppSettings.Settings.Add("language", SelectLanguage.Name);
  10.                 else
  11.                     config.AppSettings.Settings["language"].Value = SelectLanguage.Name;
  12.                 config.Save();
  13.                 ConfigurationManager.RefreshSection("appSettings");
  14.             }
  15.         }
复制代码
6、应用程序启动根据配置切换多语言

  1.    /// <summary>
  2.    /// App.xaml 的交互逻辑
  3.    /// </summary>
  4.    public partial class App : Application
  5.    {
  6.        protected override void OnStartup(StartupEventArgs e)
  7.        {
  8.            base.OnStartup(e);
  9.           var lan= ConfigurationManager.AppSettings["language"];
  10.            if (!string.IsNullOrWhiteSpace(lan))
  11.            {
  12.                CultureInfo culture = new CultureInfo(lan);
  13.                Thread.CurrentThread.CurrentCulture = culture;
  14.                Thread.CurrentThread.CurrentUICulture = culture;
  15.            }
  16.        }
  17.    }
复制代码
 7、使用

①映射定名空间
  1. xmlns:rs="clr-namespace:WpfApp8.Resources"
复制代码
②示例
  1.     <Grid>
  2.         <GroupBox x:Name="gbox">
  3.             <Grid>
  4.                 <Button Width="100"
  5.                 Height="80"
  6.                 Background="LightGray"
  7.                 Content="{x:Static rs:SRS.TestLan}" />
  8.                 <ComboBox Width="150"
  9.                   Height="50"
  10.                   HorizontalAlignment="Left"
  11.                   VerticalContentAlignment="Center"
  12.                   DisplayMemberPath="NativeName"
  13.                   ItemsSource="{Binding Path=CultureInfos, ElementName=MW}"
  14.                   SelectedItem="{Binding Path=SelectLanguage, ElementName=MW}" />
  15.             </Grid>
  16.         </GroupBox>
  17.     </Grid>
复制代码

二、多语言切换(无需重启)

安装Nuget包:WpfExtensions.Xaml
1、创建多语言标志扩展基类

  1.     /// <summary>
  2.     /// 多语言绑定扩展基类
  3.     /// </summary>
  4.     /// <typeparam name="T">多语言文件资源类</typeparam>
  5.     [MarkupExtensionReturnType(typeof(object))]
  6.     public class LanguageExtensionBase<T> : MarkupExtension where T : class
  7.     {
  8.         private static readonly ResourceConverter ResourceConverter = new ResourceConverter();
  9.         [ConstructorArgument("Key")]
  10.         public ComponentResourceKey Key { get; set; }
  11.         public LanguageExtensionBase(string key)
  12.         {
  13.             Key = new ComponentResourceKey(typeof(T), key);
  14.         }
  15.         public override object ProvideValue(IServiceProvider serviceProvider)
  16.         {
  17.             if (Key == null)
  18.             {
  19.                 throw new NullReferenceException("Key cannot be null at the same time.");
  20.             }
  21.             IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
  22.             if (provideValueTarget == null)
  23.             {
  24.                 throw new ArgumentException("The serviceProvider must implement IProvideValueTarget interface.");
  25.             }
  26.             if (provideValueTarget.TargetObject?.GetType().FullName == "System.Windows.SharedDp")
  27.             {
  28.                 return this;
  29.             }
  30.             return new Binding("Value")
  31.             {
  32.                 Source = new I18nSource(Key, provideValueTarget.TargetObject),
  33.                 Mode = BindingMode.OneWay,
  34.                 Converter = ResourceConverter
  35.             }.ProvideValue(serviceProvider);
  36.         }
  37.     }
复制代码
2、添加资源转换器

  1.     /// <summary>
  2.     /// 资源转换器
  3.     /// </summary>
  4.     public class ResourceConverter : IValueConverter
  5.     {
  6.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  7.         {
  8.             Bitmap val = (Bitmap)((value is Bitmap) ? value : null);
  9.             if (val == null)
  10.             {
  11.                 Icon val2 = (Icon)((value is Icon) ? value : null);
  12.                 if (val2 != null)
  13.                 {
  14.                     return ToBitmapSource(val2.ToBitmap());
  15.                 }
  16.                 return value;
  17.             }
  18.             return ToBitmapSource(val);
  19.         }
  20.         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  21.         {
  22.             throw new NotSupportedException();
  23.         }
  24.         [DllImport("gdi32")]
  25.         private static extern int DeleteObject(IntPtr o);
  26.         public ImageSource ToBitmapSource(Bitmap bitmap)
  27.         {
  28.             IntPtr ptr = bitmap.GetHbitmap(); //obtain the Hbitmap
  29.             BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
  30.             DeleteObject(ptr); //release the HBitmap
  31.             return bitmapSource;
  32.         }
  33.     }
复制代码
3、创建资源文件


4、继续基类创建指定资源文件扩展

  1.     /// <summary>
  2.     /// 多语言绑定扩展
  3.     /// </summary>
  4.     [MarkupExtensionReturnType(typeof(object))]
  5.     internal class LanguageExtension : LanguageExtensionBase<DefaultLanguage>
  6.     {
  7.         public LanguageExtension(string key) : base(key)
  8.         {
  9.         }
  10.     }
复制代码
5、添加资源文件管理

  1. try
  2. {
  3.     I18nManager.Instance.Add(Resource.ResourceManager);
  4. }
  5. catch (ArgumentException)
  6. {
  7. }
复制代码
6、切换语言

  1. var culture = new CultureInfo("en-US");
  2. I18nManager.Instance.CurrentUICulture = culture;
  3. System.Threading.Thread.CurrentThread.CurrentCulture = culture;
复制代码
7、使用

①映射定名空间到XAML
  1. xmlns:Lan="clr-namespace:SqlSugarTest.Lan"
复制代码
 ②资源文件中添加多语言资源

③示例
  1.                     <GroupBox Header="多语言测试">
  2.                         <Menu Height="NaN" HorizontalAlignment="Center"
  3.                           VerticalAlignment="Center"
  4.                           Background="{x:Null}"
  5.                           FontSize="12" FontWeight="Bold">
  6.                             <MenuItem Margin="3" Padding="10,8"
  7.                                   HorizontalAlignment="Center"
  8.                                   HorizontalContentAlignment="Center"
  9.                                   Header="{Lan:Language MultiLanguage}">
  10.                                 <MenuItem Margin="3" Padding="10,5"
  11.                                       Click="MenuItem_Click_CN" Header="CN-中" />
  12.                                 <MenuItem Margin="3" Padding="10,5"
  13.                                       Click="Button_Click_EN" Header="US-英" />
  14.                                 <MenuItem Margin="3" Padding="10,5"
  15.                                       Header="Test">
  16.                                     <MenuItem Margin="3" Padding="10,5"
  17.                                           Header="111" />
  18.                                     <MenuItem Margin="3" Padding="10,5"
  19.                                           Header="222" />
  20.                                 </MenuItem>
  21.                             </MenuItem>
  22.                         </Menu>
  23.                     </GroupBox>
复制代码
8、后台使用多语言

①获取多语言资源字符串

  1.         /// <summary>
  2.         /// 获取Key资源
  3.         /// </summary>
  4.         /// <param name="key"></param>
  5.         /// <param name="resource"></param>
  6.         /// <returns></returns>
  7.         public static string GetString(string key, ResourceManager resource = null)
  8.         {
  9.             if (resource == null)
  10.                 return DefaultLanguage.ResourceManager.GetString(key, I18nManager.Instance.CurrentUICulture);
  11.             else
  12.                 return resource.GetString(key, I18nManager.Instance.CurrentUICulture);
  13.         }
复制代码
  1. MessageBox.Show(GetString(nameof(DefaultLanguage.Test)));
复制代码

②后台绑定

  1.         static readonly ResourceConverter converter = new ResourceConverter();
  2.         /// <summary>
  3.         /// 按自定义数据绑定多语言
  4.         /// </summary>
  5.         /// <typeparam name="T">自定义数据源</typeparam>
  6.         /// <param name="key">数据关键字</param>
  7.         /// <returns></returns>
  8.         public static BindingBase GetBinding<T>(string key, object element = null)
  9.         {
  10.             var Key = new ComponentResourceKey(typeof(T), key);
  11.             return new Binding("Value")
  12.             {
  13.                 Source = new I18nSource(Key, element),
  14.                 Mode = BindingMode.OneWay,
  15.                 Converter = converter
  16.             };
  17.         }
复制代码
  1. menu_Test.SetBinding(MenuItem.HeaderProperty, GetBinding<DefaultLanguage>(nameof(DefaultLanguage.Test)));
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表