首页 > 其他分享 >WPF-实现多语言的静态(需重启)与动态切换(不用重启)

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

时间:2024-08-14 13:22:41浏览次数:6  
标签:语言 静态 重启 object Key new WPF null public

目录

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

1、配置文件添加Key

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

3、创建资源文件

 4、初始化多语言集合

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

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

 7、使用

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

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

2、添加资源转换器

3、创建资源文件

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

5、添加资源文件管理

6、切换语言

7、使用

8、后台使用多语言

①获取多语言资源字符串

②后台绑定


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

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<DefaultLanguage>
    {
        public LanguageExtension(string key) : base(key)
        {
        }
    }

5、添加资源文件管理

try
{
    I18nManager.Instance.Add(Resource.ResourceManager);
}
catch (ArgumentException) 
{
}

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>

8、后台使用多语言

①获取多语言资源字符串

        /// <summary>
        /// 获取Key资源
        /// </summary>
        /// <param name="key"></param>
        /// <param name="resource"></param>
        /// <returns></returns>
        public static string GetString(string key, ResourceManager resource = null)
        {
            if (resource == null)
                return DefaultLanguage.ResourceManager.GetString(key, I18nManager.Instance.CurrentUICulture);
            else
                return resource.GetString(key, I18nManager.Instance.CurrentUICulture);
        }
MessageBox.Show(GetString(nameof(DefaultLanguage.Test)));

②后台绑定

        static readonly ResourceConverter converter = new ResourceConverter();

        /// <summary>
        /// 按自定义数据绑定多语言
        /// </summary>
        /// <typeparam name="T">自定义数据源</typeparam>
        /// <param name="key">数据关键字</param>
        /// <returns></returns>
        public static BindingBase GetBinding<T>(string key, object element = null)
        {
            var Key = new ComponentResourceKey(typeof(T), key);
            return new Binding("Value")
            {
                Source = new I18nSource(Key, element),
                Mode = BindingMode.OneWay,
                Converter = converter
            };
        }
 menu_Test.SetBinding(MenuItem.HeaderProperty, GetBinding<DefaultLanguage>(nameof(DefaultLanguage.Test)));

标签:语言,静态,重启,object,Key,new,WPF,null,public
From: https://blog.csdn.net/rwo_bear/article/details/140918651

相关文章

  • HTML静态网页成品作业(HTML+CSS)——古诗词网设计制作(5个页面)
    ......
  • CAD二次开发入门:WPF类库
     参考学习视频:https://www.bilibili.com/video/BV16Y411v7kr/?spm_id_from=333.337.search-card.all.click&vd_source=fbb64ea20b269b753497bf6c2499fc29 第一步:创建WPF类库,并写CAD调用方法  修改输出类型为:类库 添加CAD开发需要的类库 main页面添加以下内容:......
  • wpf ValidationRule 校验数据输入
    publicclassCountValidationRule:ValidationRule{publicoverrideValidationResultValidate(objectvalue,System.Globalization.CultureInfocultureInfo){doubled=0.0;if(double.TryParse((string)value,out......
  • 【WPF】【XAML】Exception: 无法找到名为“xx”的资源。资源名称区分大小写。
    <Grid.Resources>一定要放在使用之前,比如<ListBoxName="peopleListBox"Grid.Column="1"Grid.Row="2"ItemsSource="{BindingSource={StaticResourceExpenseDataSource},XPath=Person}"ItemTemplate="{StaticResour......
  • 【CentOS 】DHCP 更改为静态 IP 地址并且遇到无法联网
    文章目录引言解决方式标题1.**编辑网络配置文件**:标题2.**确保配置文件包含以下内容**:特别注意标题3.**重启网络服务**:标题4.**检查配置是否生效**:标题5.**测试网络连接**:标题6.**检查路由表**:标题7.**检查防火墙设置**:标题8.**检查SELinux状态**:标题9.**检......
  • Linux应用程序重启:优雅实现应用程序的自动重启
    简介:在Linux服务器运行应用程序时,如果应用程序出现崩溃或异常终止,为保证服务的可靠性,自动重启是一种常见的应对措施。本文将介绍Linux下实现应用程序自动重启的方法,并提供代码实现例子,帮助读者优雅地处理应用程序的崩溃和重启。1.使用init或systemd管理器Linux系统中通常有i......
  • C++静态函数
    由于本人C++小白,关于C++的很多基础概念都不太理解,在工作当中遇到了静态函数,在函数的使用和调用外部函数与普通函数还是非常不一样的,故这里向AI请教,简单做个记录。AI的回答内容如下:Yousaid:C++当中静态函数的优势是什么ChatGPTsaid:在C++中,静态函数(static函数)是指通过在函......
  • nginx反向代理配置https和http能同时访问后,发现一些页面使用http访问正常,使用https访
    报错:Thisrequesthasbeenblocked;thecontentmustbeservedoverHTTPS,如下图: 问题原因:HTTPS页面里动态的引入了HTTP资源,比如引入一个js文件,会被直接block掉的.在HTTPS页面里通过AJAX的方式请求HTTP资源,也会被直接block掉。 解决方法一:(没试过,要改的页面太多了,没有使......
  • Alpine Linux下同时绑定DHCP与静态地址
    官方教程:https://wiki.alpinelinux.org/wiki/Configure_NetworkingAlpine官方文档只介绍了如何给网卡设置动态或者静态地址,没有提及两者兼顾。使用主机进行测试,可同时实现dhcp与静态地址共存。注意:这里绑定的是唯一本地地址,可内部自由分配保证网内唯一即可。ipv6各类地址介绍......
  • centos 配置静态ip
    1、查看ip地址[root@localhostnetwork-scripts]#ipaddr1:lo:<LOOPBACK,UP,LOWER_UP>mtu65536qdiscnoqueuestateUNKNOWNgroupdefaultqlen1000link/loopback00:00:00:00:00:00brd00:00:00:00:00:00inet127.0.0.1/8scopehostlovalid_......