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

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

1、配置文件添加Key

XML 复制代码
	<appSettings>
		<add key="language" value="zh-CN"/>
	</appSettings>

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

cs 复制代码
        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、初始化多语言集合

cs 复制代码
        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、切换多语言并更新配置文件

cs 复制代码
        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、应用程序启动根据配置切换多语言

cs 复制代码
   /// <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、使用

①映射命名空间

XML 复制代码
xmlns:rs="clr-namespace:WpfApp8.Resources"

②示例

XML 复制代码
    <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、创建多语言标记扩展基类

cs 复制代码
    /// <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、添加资源转换器

cs 复制代码
    /// <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、继承基类创建指定资源文件扩展

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

5、添加资源文件管理

cs 复制代码
 I18nManager.Instance.Add(Resource.ResourceManager);

6、切换语言

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

7、使用

①映射命名空间到XAML

XML 复制代码
xmlns:Lan="clr-namespace:SqlSugarTest.Lan"

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

③示例

XML 复制代码
                    <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>
相关推荐
IT规划师3 小时前
开源 - Ideal库 - 常用枚举扩展方法(一)
开源·c#·.net core·ideal库·枚举转换
NetX行者9 小时前
.NET 9震撼来袭:基于.NET 8的五大功能亮点,引领开发新潮流
开发语言·microsoft·c#·.netcore
张某布响丸辣9 小时前
HTTP状态码详解
java·网络·python·网络协议·http·c#
飞舞的哈哈10 小时前
C# 有趣的小程序—桌面精灵详细讲解
c#
Skyshin3412 小时前
C# IEnumerator,IEnumerable ,Iterator
开发语言·c#
ling1s12 小时前
C#核心(7)索引器
开发语言·c#
LKID体13 小时前
win32com库基于wps对Word文档的基础操作
c#·word·wps
金蝶软件小李14 小时前
vector和docker的区别?
开发语言·docker·c#
Crazy Struggle14 小时前
.NET 8.0 通用管理平台,支持模块化、WinForms 和 WPF
vue·wpf·winform·.net 8.0·通用权限管理
金蝶软件小李15 小时前
图像处理椒盐噪声
开发语言·图像处理·算法·计算机视觉·c#