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 …...
2025终极指南:如何快速解锁雀魂全角色皮肤?Mod工具使用全攻略
2025终极指南:如何快速解锁雀魂全角色皮肤?Mod工具使用全攻略 【免费下载链接】majsoul_mod_plus 雀魂解锁全角色、皮肤、装扮等,支持全部服务器。 项目地址: https://gitcode.com/gh_mirrors/ma/majsoul_mod_plus 还在为无法体验雀魂…...
LabelMe高级应用:如何利用AI辅助标注提升效率300%
LabelMe高级应用:如何利用AI辅助标注提升效率300% LabelMe是一款强大的图像标注工具,支持多边形、矩形、圆形、线条、点和图像级标记等多种标注方式。对于AI训练数据准备工作而言,高效的标注工具能显著提升工作流效率。本文将详细介绍如何利…...
终极ThinkPad风扇控制指南:如何让你的笔记本更安静更高效?
终极ThinkPad风扇控制指南:如何让你的笔记本更安静更高效? 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 你是否曾经被ThinkPad风扇的噪音困扰…...
【STM32-HAL库】火焰传感器实战:从原理到智能火灾预警系统搭建(基于STM32F407ZGT6)
1. 火焰传感器原理与选型指南 火焰传感器作为火灾预警系统的"眼睛",其核心原理是利用光电效应检测火焰特有的光谱特征。我经手过的工业项目中,90%的火灾误报都源于传感器选型不当。市面上常见的火焰传感器主要分为三类: 红外型&…...
后端架构师转型AI智能体架构师:3个月实战路径,收藏这份落地指南
如果你本身就是后端/全栈/架构师出身,这意味着你已经有了一套非常扎实的“确定性系统”的构建能力——分布式、高并发、数据库事务、系统稳定性,这些都是你的底牌。 而AI智能体恰恰是“不确定性系统”(大模型)与“确定性系统”&am…...
若依前后端分离系统生产环境部署:从零到上线的保姆级教程
若依前后端分离系统生产环境部署实战指南 引言:为什么选择若依框架? 对于刚接触企业级开发的新手来说,若依(RuoYi)框架无疑是一个绝佳的起点。这个基于Spring Boot和Vue.js的前后端分离架构,不仅提供了完善的权限管理、代码生成等…...
STM32上如何用串口BREAK中断优雅处理DMX与RDM协议(附完整代码)
STM32串口BREAK中断实现DMX/RDM协议双模通信实战指南 舞台灯光控制系统对实时性和可靠性有着近乎苛刻的要求。作为行业标准的DMX512协议及其扩展协议RDM,承载着数以万计舞台灯具的控制指令。传统基于STM32的软件轮询检测方案常面临响应延迟、误触发等问题࿰…...
ArcSWAT实战避坑指南 | 从数据库配置到模型运行,详解常见报错与高效解决方案
1. ArcSWAT入门避坑:从安装到首次运行的关键准备 第一次接触ArcSWAT的水文研究者,往往会在安装环节就踩坑。我见过太多人因为版本兼容性问题,导致后续模型根本无法启动。这里分享几个血泪教训: ArcGIS版本选择是首要关键。虽然官方…...
最完整的llm-graph-builder入门指南:从安装到知识图谱可视化
最完整的llm-graph-builder入门指南:从安装到知识图谱可视化 【免费下载链接】llm-graph-builder Neo4j graph construction from unstructured data 项目地址: https://gitcode.com/GitHub_Trending/ll/llm-graph-builder 你还在为非结构化数据转化为结构化…...
ICML 2023亚马逊论文速览:自适应计算与差分隐私
机器学习 某机构在ICML 2023会议论文速览 在一系列主题中,某机构的研究融合了理论与实践的探索。 会议 ICML 2023 在今年的国际机器学习大会(ICML)上,某机构的研究人员发表了多篇关于赌博机问题和差分隐私的论文,这两个…...
