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

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

1、配置文件添加Key

	<appSettings>
		<add key="language" value="zh-CN"/>
	</appSettings>

2、新增附加属性当前选择语言

        public CultureInfo SelectLanguage
        {
            get => (CultureInfo)GetValue(SelectLanguageProperty);
            set => SetValue(SelectLanguageProperty, value);
        }

        public static readonly DependencyProperty SelectLanguageProperty =
            DependencyProperty.Register("SelectLanguage", typeof(CultureInfo), typeof(MainWindow));

3、创建资源文件

 4、初始化多语言集合

        public ObservableCollection<CultureInfo> CultureInfos { get; private set; } = new ObservableCollection<CultureInfo>();

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var dir =Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var curs = CultureInfo.GetCultures(CultureTypes.AllCultures);
            foreach (CultureInfo cur in curs)
            {
                if (string.IsNullOrWhiteSpace(cur.Name)) continue;
                string landir = Path.Combine(dir, cur.Name);
                if (Directory.Exists(landir)) CultureInfos.Add(cur);
            }
            if (CultureInfos.Any(cur => cur.Name.Equals("zh-CN", StringComparison.OrdinalIgnoreCase)) is false)
            {
                var cur = curs.FirstOrDefault(c => c.Name.Equals("zh-CN", StringComparison.OrdinalIgnoreCase));
                if (cur != null) CultureInfos.Add(cur);
            }
            SelectLanguage = Thread.CurrentThread.CurrentCulture;
        }

5、切换多语言并更新配置文件

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == SelectLanguageProperty)
            {
                if (SelectLanguage == Thread.CurrentThread.CurrentCulture) return;
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                if (ConfigurationManager.AppSettings["language"] is null)
                    config.AppSettings.Settings.Add("language", SelectLanguage.Name);
                else
                    config.AppSettings.Settings["language"].Value = SelectLanguage.Name;
                config.Save();
                ConfigurationManager.RefreshSection("appSettings");
            }
        }

6、应用程序启动根据配置切换多语言

   /// <summary>
   /// App.xaml 的交互逻辑
   /// </summary>
   public partial class App : Application
   {
       protected override void OnStartup(StartupEventArgs e)
       {
           base.OnStartup(e);
          var lan= ConfigurationManager.AppSettings["language"];
           if (!string.IsNullOrWhiteSpace(lan))
           {
               CultureInfo culture = new CultureInfo(lan);
               Thread.CurrentThread.CurrentCulture = culture;
               Thread.CurrentThread.CurrentUICulture = culture;
           }
       }
   }

 7、使用

①映射命名空间

xmlns:rs="clr-namespace:WpfApp8.Resources"

②示例

    <Grid>
        <GroupBox x:Name="gbox">
            <Grid>
                <Button Width="100"
                Height="80"
                Background="LightGray"
                Content="{x:Static rs:SRS.TestLan}" />
                <ComboBox Width="150"
                  Height="50"
                  HorizontalAlignment="Left"
                  VerticalContentAlignment="Center"
                  DisplayMemberPath="NativeName"
                  ItemsSource="{Binding Path=CultureInfos, ElementName=MW}"
                  SelectedItem="{Binding Path=SelectLanguage, ElementName=MW}" />
            </Grid>
        </GroupBox>
    </Grid>

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

安装Nuget包:WpfExtensions.Xaml

1、创建多语言标记扩展基类

    /// <summary>
    /// 多语言绑定扩展基类 
    /// </summary>
    /// <typeparam name="T">多语言文件资源类</typeparam>
    [MarkupExtensionReturnType(typeof(object))]
    public class LanguageExtensionBase<T> : MarkupExtension where T : class
    {
        private static readonly ResourceConverter ResourceConverter = new ResourceConverter();
        [ConstructorArgument("Key")]
        public ComponentResourceKey Key { get; set; }

        public LanguageExtensionBase(string key)
        {
            Key = new ComponentResourceKey(typeof(T), key);
        }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Key == null)
            {
                throw new NullReferenceException("Key cannot be null at the same time.");
            }

            IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if (provideValueTarget == null)
            {
                throw new ArgumentException("The serviceProvider must implement IProvideValueTarget interface.");
            }

            if (provideValueTarget.TargetObject?.GetType().FullName == "System.Windows.SharedDp")
            {
                return this;
            }

            return new Binding("Value")
            {
                Source = new I18nSource(Key, provideValueTarget.TargetObject),
                Mode = BindingMode.OneWay,
                Converter = ResourceConverter
            }.ProvideValue(serviceProvider);
        }
    }

2、添加资源转换器

    /// <summary>
    /// 资源转换器
    /// </summary>
    public class ResourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Bitmap val = (Bitmap)((value is Bitmap) ? value : null);
            if (val == null)
            {
                Icon val2 = (Icon)((value is Icon) ? value : null);
                if (val2 != null)
                {
                    return ToBitmapSource(val2.ToBitmap());
                }
                return value;
            }
            return ToBitmapSource(val);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        [DllImport("gdi32")]
        private static extern int DeleteObject(IntPtr o);
        public ImageSource ToBitmapSource(Bitmap bitmap)
        {
            IntPtr ptr = bitmap.GetHbitmap(); //obtain the Hbitmap
            BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            DeleteObject(ptr); //release the HBitmap
            return bitmapSource;
        }
    }

3、创建资源文件

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

    /// <summary>
    /// 多语言绑定扩展
    /// </summary>
    [MarkupExtensionReturnType(typeof(object))]
    internal class LanguageExtension : LanguageExtensionBase<Resource>
    {
        public LanguageExtension(string key) : base(key)
        {
        }
    }

5、添加资源文件管理

 I18nManager.Instance.Add(Resource.ResourceManager);

6、切换语言

var culture = new CultureInfo("en-US");
I18nManager.Instance.CurrentUICulture = culture;
System.Threading.Thread.CurrentThread.CurrentCulture = culture;

7、使用

①映射命名空间到XAML

xmlns:Lan="clr-namespace:SqlSugarTest.Lan"

 ②资源文件中添加多语言资源

③示例

                    <GroupBox Header="多语言测试">
                        <Menu Height="NaN" HorizontalAlignment="Center"
                          VerticalAlignment="Center"
                          Background="{x:Null}"
                          FontSize="12" FontWeight="Bold">
                            <MenuItem Margin="3" Padding="10,8"
                                  HorizontalAlignment="Center"
                                  HorizontalContentAlignment="Center"
                                  Header="{Lan:Language MultiLanguage}">
                                <MenuItem Margin="3" Padding="10,5"
                                      Click="MenuItem_Click_CN" Header="CN-中" />
                                <MenuItem Margin="3" Padding="10,5"
                                      Click="Button_Click_EN" Header="US-英" />
                                <MenuItem Margin="3" Padding="10,5"
                                      Header="Test">
                                    <MenuItem Margin="3" Padding="10,5"
                                          Header="111" />
                                    <MenuItem Margin="3" Padding="10,5"
                                          Header="222" />
                                </MenuItem>
                            </MenuItem>
                        </Menu>
                    </GroupBox>

  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值