WPF-实现多语言的静态(需重启)与动态切换(不用重启)
目录
一、多语言切换(需重启)
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);elseconfig.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 HbitmapBitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());DeleteObject(ptr); //release the HBitmapreturn 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);elsereturn 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)));
相关文章:
WPF-实现多语言的静态(需重启)与动态切换(不用重启)
目录 一、多语言切换(需重启) 1、配置文件添加Key 2、新增附加属性当前选择语言 3、创建资源文件 4、初始化多语言集合 5、切换多语言并更新配置文件 6、应用程序启动根据配置切换多语言 7、使用 二、多语言切换(无需重启)…...
UE5学习笔记12-为角色添加蹲下的动作
一、一点说明 1.蹲下使用了ACharacter类中Crouch();函数,函数功能是先检查是否存在运动组件,将bool类型的变量变为true,该变量代表是想要蹲下。 2.通过源码可知存在是否蹲下的bool变量bIsCrouched如图,如果对:1有疑问请搜索C位域 …...
【笔记】Android 多用户模式和用户类型
简介 用户界面:System 》Multiple Users 》 开关多用户模式。 一般是不同用户模式下,有修改Settings应用配置的权限差异,因此需要通过用户类型对功能进行判断限制。 代码 通过UserManager可以获取当前用户的信息。 frameworks/base/core/…...
SQL基础——MySQL的索引
简介:个人学习分享,如有错误,欢迎批评指正。 一、概述 介绍 索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表&…...
【开发语言】面向对象和面向过程开发思路的区别
引入: 我总结了 面向过程的开发语言思路:1.我要干啥?2.怎么才能实现 面向对象的开发语言思路:1.我要研究谁?2.他能干啥 详解: 面向过程的开发语言思路 我要干啥? 在面向过程的开发中&a…...
谷歌账号登录的时候提示被停用,原因是什么,账号还有救吗?该如何处理?
今日早上,有个久违的朋友找到我说,要恢复账号。 他的情况是这样的:7月21日的时候,他发现自己的谷歌账号登录的时候提示活动异常先,需要输入手机号码验证才能恢复账号。但是输入了自己和亲友们的多个手机号码都无法验证…...
数据库复习笔记
写在最前, 写文章的初衷只是为了复习与记录自己的成长,笔者目前水平还有待提高,文章中难免会出现许多问题与错误,文章内容仅供参考,有不足的地方还请大家多多包涵并指正,谢谢~ 第八章 T-SQL程序结构 8.…...
学习STM32(6)-- STM32单片机ADCDAC的应用
1 引 言 深入了解并掌握STM32F103单片机在模拟数字转换(ADC)和数字模拟转换(DAC)应用方面的功能和操作。学习如何配置STM32F103的ADC模块,实现模拟信号到数字信号的精确转换;同时,探索DAC模块…...
学习记录第二十五天
wait函数 wait函数是一个系统调用,用于等待一个子进程结束并回收其资源。当父进程调用wait函数时,它会暂停执行,直到至少有一个子进程结束。wait函数的原型如下: #include <sys/types.h> #include <sys/wait.h>pid_…...
C语言:字符串函数strcmp
该函数用于比较两个字符串是否一样。 使用方法如下: #include<stdio.h> #include<string.h>int main() {//strcmp函数返回值有三种情况,小于零时返回-1,等于零,大于零时返回1printf("%d\n", strcmp("…...
【数据分析---偏企业】 Excel操作
各位大佬好 ,这里是阿川的博客,祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 Excel操作前 必看 Python 初阶 Python—语言基础与…...
Ajax-01.原生方式
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Ajax-原生方式</title> </head> <!-…...
OpenAI GPT-2 model use with TensorFlow JS
题意:使用 TensorFlow JS 应用 OpenAI GPT-2 模型 问题背景: Is that possible to generate texts from OpenAI GPT-2 using TensorFlowJS? 是否可以使用 TensorFlowJS 生成 OpenAI GPT-2 的文本? If not what is the limitation, like mo…...
JVM-运行数据区(堆、栈、元空间)
文章声明:文章图片均来自互联网,因为本人画的图不够生动。 运行数据区是JVM最重要的一个区域。 运行数据区由栈、堆、元空间构成。 栈:程序计数器、JVM虚拟机栈,本地方法栈 本地方法栈:加载native修饰的方法&#…...
超详细!!! LVS(Linux virual server)负载均衡知识及其NAT模式、DR模式、火墙标记实验
目录 前言系统性能扩展方式集群Cluster分布式集群与分布式 四层转发与七层转发的区别 LVS(Linux virual server)一、LVS介绍LVS相关概念 二、LVS集群结构体系1. 负载均衡层(Load Balancer)2. 服务器群组层(Server Pool…...
信息学奥赛一本通1259:【例9.3】求最长不下降序列
题目: 1259:【例9.3】求最长不下降序列 时间限制: 1000 ms 内存限制: 65536 KB 提交数:51218 通过数: 20928 Special Judge 【题目描述】 设有由n(1≤n≤200)n(1≤n≤200)个不相同的整数组成的数列,记为:b(1)、b(2)、……、…...
星露谷模组开发教程#3 事件
首发于Enaium的个人博客 SMAPI提供了一些事件,比如游戏的内容、显示、输入等事件。这些事件可以让我们在游戏中添加自己的逻辑。这一节我们就来看看如何使用这些事件。 注册一个事件 在SMAPI中,我们可以通过IModHelper的Events属性来注册事件。比如我们…...
C语言程序设计(初识C语言后部分)
愿天下无Bug,秀发常驻。 3)函数的参数 1.实际参数(实参): 真实传给函数的参数,叫实参。 实参可以是:常量、变量、表达式、函数等。 无论实参是何类型的量,在进行函数调用时&#…...
驱动基础开发
1、字符设备传统开发模板 字符设备驱动框架,首先我们需要去用module_init这个宏去修饰整个驱动的入口函数,用module_exit去修饰整个驱动的出口函数,然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设…...
从苹果AppStore看AI开发者生态
从苹果 App Store 看 AI 开发者生态 在人工智能迅速发展的今天,我们不禁要问:未来的 AI 开发者生态将会是什么样子?为了回答这个问题,我们不妨回顾一下移动互联网时代最成功的开发者生态之一——苹果的 App Store。 通过分析 App …...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
