WinForm 中用 Localizable
属性 + 卫星程序集实现多语言
WinForm 多语言本质是资源文件驱动,不是运行时动态改控件文本。关键在于把界面字符串抽成
.resx,再为每种语言生成对应卫星程序集。
Form或
UserControl的
Localizable属性必须设为
true(在设计器属性面板里改),否则 VS 不会生成
Form.zh-CN.resx这类文件 语言切换不是靠代码“重载”界面,而是靠线程当前
Thread.CurrentThread.CurrentUICulture决定加载哪个
.resources文件 切语言前必须重启窗体:新建实例 → 设置
CurrentUICulture→ 显示,否则已有窗体不会刷新文本 资源文件里键名必须和设计器生成的完全一致,比如
button1.Text,手动改键名会导致该控件文本回退到默认值
Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN");
var form = new MainForm();
form.Show();
WPF 中用 Uid
+ msbuild
生成 .g.resources
实现多语言
WPF 没有内置
Localizable开关,得靠
Uid属性标记元素,再用
MSBuild工具链生成本地化资源。流程比 WinForm 更底层、更易出错。 每个需要翻译的控件必须显式加
Uid属性(如
<button uid="Button_1"></button>),VS 设计器不自动加,漏一个就无法提取该控件文本 项目文件需启用本地化:
<uiculture>en-US</uiculture>,并确保
<generatetemporarytargetassembly>true</generatetemporarytargetassembly>翻译后的
.csproj要引用对应
.resources文件,路径必须是
zh-CN\YourApp.resources.dll,放错目录或命名不符会导致运行时报
MissingManifestResourceExceptionWPF 不支持运行时切换语言后重绘现有窗口,必须关闭旧窗体、重建新窗体,并确保新窗体构造前已设置
Thread.CurrentThread.CurrentUICulture
共用资源文件(.resx)在 WinForm/WPF 间复用的坑
想让 WinForm 和 WPF 共享同一套中文/英文资源?可以,但要注意资源访问方式差异导致的硬编码风险。
WinForm 自动生成的Resources.Designer.cs是静态类,调用如
Resources.String1;WPF 默认用
Properties.Resources.ResourceManager.GetString("String1"),两者底层都读 .resources,但命名空间和访问路径不同 若手动把 WinForm 的
Resources.resx拖进 WPF 项目,必须右键属性 →
Custom Tool改为
PublicResXFileCodeGenerator,否则生成的类是 internal,WPF XAML 绑定不到 WPF 的
Binding无法直接绑到
Resources.String1(非依赖属性),得用
x:Static或写转换器,例如:
{x:Static properties:Resources.String1}
资源键名含空格或点号(如 login.button.text)在 WPF 中会被编译器拒绝,WinForm 倒是允许,统一建议用驼峰(
LoginButtonText)
运行时切换语言失败的三个高频原因
多数人卡在“改了 Culture 却没变语言”,问题往往不在逻辑,而在执行时机或资源加载路径。
没调用Application.Current.Shutdown()或关闭所有窗体就新建窗体 → 旧窗体仍持有原
ResourceManager实例,新窗体才生效 程序集未生成卫星程序集 → 检查输出目录是否有
zh-CN\YourApp.resources.dll,没有说明
resgen或
al.exe步骤失败,或项目未设
<supportedcultures>zh-CN;ja-JP</supportedcultures>资源文件名大小写错误 → Windows 下
zh-cn和
zh-CN被视为不同文化,但 .NET 运行时只认标准格式(
zh-CN),用错就 fallback 到默认资源
真正麻烦的是资源键同步:WinForm 控件名改了,WPF 的
Uid没同步,或者翻译人员改了
.resx键但忘了通知开发更新
Uid—— 这类问题不会报错,只会静默显示英文。
