WPF使用x:Uid与resx实现运行时本地化时按钮文本为何为空
WPF x:Uid 本地化按钮文本为空问题排查与解决
当前配置现状
已完成的本地化相关配置:
- App.cs中手动配置全链路文化信息为zh-CN,对应代码:
CultureInfo culture = new CultureInfo("zh-CN"); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; Thread.CurrentThread.CurrentUICulture = culture; Thread.CurrentThread.CurrentCulture = culture;
- 在自定义路径
/Language/zh-CN/下放置Resources.resx,已配置本地化键值对:Control_ConnectButton.Content:连接Control_TestButton.Content:测试
- 两个Button控件通过x:Uid关联对应资源键,启动应用后按钮文本完全为空,开发环境为.NET Framework 4.6.1。
问题根源
按照.NET Framework 4.6.1下WPF内置的x:Uid本地化机制,当前配置存在3个直接导致文本为空的偏差:
- 资源路径与生成配置不匹配内置查找规则
WPF的x:Uid机制默认从程序集的固定嵌入资源路径下,结合当前线程UICulture定位资源流。将resx放在自定义的/Language/zh-CN/路径下时,若未手动调整资源的逻辑嵌入名称、设置正确的生成操作,程序完全无法定位到你写入的资源内容。
文化资源的匹配规则要求:必须存在中性语言的默认Resources.resx作为查找兜底,对应特定文化的资源需要放在固定的嵌入路径下,而非自定义文件夹中。 - 文化设置时机早于控件初始化阶段的资源读取
如果zh-CN的文化配置没有在窗口执行InitializeComponent()前完成,窗口初始化时会按照系统默认文化(如en-US)查找资源,找不到匹配键时会将对应属性值设为null,直接表现为文本为空。 - x:Uid本身不支持自动响应文化变更
x:Uid的资源绑定是一次性读取逻辑,仅在控件初始化时读取一次对应资源值,不会监听文化变更自动刷新。即便资源配置完全正确,如果文化设置晚于控件初始化,已经渲染的控件不会自动加载新的资源值。
修正方案
- 调整resx的存放结构与生成配置
- 将默认中性语言的
Resources.resx放在项目根目录的Properties文件夹下,设置生成操作为嵌入的资源,访问修饰符设为Public - 将对应zh-CN文化的
Resources.zh-CN.resx同步放在Properties路径下,取消之前自定义的/Language/zh-CN/路径 - 保留你当前编写的资源键格式(
{x:Uid值}.{目标依赖属性名})即可,无需修改
- 将默认中性语言的
- 调整文化设置的执行时机
重写App的OnStartup方法,在调用base.OnStartup(e)、也就是主窗口初始化之前完成全局文化赋值,确保控件执行InitializeComponent()时,当前线程的UICulture已经是目标语言 - 补全运行时语言切换的刷新逻辑
切换语言时,需要手动重新执行当前窗口的InitializeComponent(),或遍历可视树所有元素,根据元素的Uid值重新读取对应资源的属性值,完成界面文本的刷新。
注意:如果坚持使用自定义路径存放resx,必须手动将资源的逻辑嵌入名称设置为
{项目根命名空间}.g.resources下的对应资源流,否则WPF内置的x:Uid查找逻辑无法定位到你的资源文件。
内容的提问来源于stack exchange,提问作者Hhry
相关产品推荐
相关产品推荐

