ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WPF 本地化重构:从 strings.resx 到常量字符串的 ResourceID 迁移全指南

WPF 本地化重构:从 strings.resx 到常量字符串的 ResourceID 迁移全指南 桌面应用前端UI组件【免费下载链接】wpfWPF is a .NET Core UI framework for building Windows desktop applications.项目地址https://gitcode.com/gh_mirrors/wp/wpf点击查看免费下载本篇技术指南以 localization_untranslated_strings.md 为核心骨架系统梳理 WPF 开源仓库gh_mirrors/wp/wpf中三类资源标识符ResourceID从strings.resx文件迁移为 C#const string常量字符串的完整方案。文中覆盖 PresentationBuildTasks、PresentationCore、PresentationFramework 三个程序集共 150 个资源项的迁移清单、各资源在源码中的实际消费位置以及迁移后本地化工作流xlf 翻译文件、SR 类型访问器的变化帮助开发者在贡献或维护 WPF 本地化资源时快速定位常量、理解键值语义并规避字符串未翻译类问题。一、背景为什么要把 ResourceID 从 resx 迁移到常量字符串在 WPF 的早期实现中大量与命令快捷键KeyGesture、构建任务名称、错误消息相关的字符串存放在程序集的Resources/Strings.resx资源文件中通过生成的强类型SRString Resources访问器以SR.XXX形式读取。这种方式的缺陷在于延迟加载与间接性SR.XXX在运行时才从资源程序集中解析字符串构建任务、命令系统每次需要字符串时都多一层资源查找且字符串值而非键名散落在.resx中难以静态追踪。本地化噪音这些字符串中一类如任务名FileClassifier、快捷键CtrlC不需要也不应该被翻译却仍被纳入 xlf 翻译流程产生大量未翻译字符串untranslated strings噪音——这正是本文档标题的由来。不利于增量编译与裁剪字符串驻留在资源文件里编译器难以判断哪些是纯内部标识、哪些是面向用户的本地化文本。迁移方案的核心思想是将非本地化的字符串直接内联为 C# 的const string常量字段与代码同编译、同裁剪而真正面向用户的显示文本如XXXKeyDisplayString后缀的资源继续保留在Strings.resx/.xlf中走正常本地化流程。二、PresentationBuildTasks构建任务标识常量化2.1 迁移清单完整表格PresentationBuildTasks程序集源码位于 src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks共迁移了 8 个任务名常量它们是 MSBuild 目标中引用的任务类名ResourceIDValue常量值FileClassifierTaskFileClassifierGetWinFXPathTaskGetWinFXPathMarkupCompilePass1TaskMarkupCompilePass1MarkupCompilePass2TaskMarkupCompilePass2MergeLocalizationDirectivesTaskMergeLocalizationDirectivesResourcesGeneratorTaskResourcesGeneratorUidManagerTaskUidManagerUpdateManifestForBrowserApplicationTaskUpdateManifestForBrowserApplication2.2 这些常量的真实消费位置MarkupCompilePass1/MarkupCompilePass2是 WPF XAML 编译管线的两个核心阶段。构建入口文件 Microsoft.WinFX.targets 中定义了名为MarkupCompilePass1的Target并在 第 92 行 通过TargetsMarkupCompilePass1建立依赖MergeLocalizationDirectives目标定义于 第 909 行。源码中任务类型被大量引用如 CompilerWrapper.cs 的注释明确指出该属性由 MarkupCompilePass1 与 Pass2 构建任务调用TaskFileService.cs 通过_buildTask as MarkupCompilePass1进行类型判断IncrementalCompileAnalyzer.cs 构造器接收MarkupCompilePass1实例用于增量编译分析。ResourcesGenerator的静态方法GetResourceIdForResourceFile在 MarkupCompiler.cs 中被调用用于生成 BAML 资源的规范化资源 ID由源文件相对路径、TargetPath、当前目录等拼合而成随后参与构造形如/{AssemblyName}/component/{resourceID}的组件 URI见 MarkupCompiler.cs。迁移收益这些任务名是 MSBuild 内部契约字符串若进入 resx 翻译流程毫无意义。常量化后任务名与任务类定义共存于同一编译单元ResourceManager查找被彻底消除。三、PresentationCore命令快捷键与硬件错误消息常量化PresentationCore源码位于 src/Microsoft.DotNet.Wpf/src/PresentationCore迁移了两大类内容应用/导航命令的默认键位绑定约 40 个与1 条硬件错误消息。3.1 完整迁移清单ResourceIDValue常量值BrowseBackKeyAltLeft;BackspaceBrowseForwardKeyAltRight;ShiftBackspaceBrowseHomeKeyAltHome;BrowserHomeBrowseStopKeyAltEsc;BrowserStopContextMenuKeyShiftF10;AppsCopyKeyCtrlC;CtrlInsertCutKeyCtrlX;ShiftDeleteDeleteKeyDelExtendSelectionDownKeyShiftDownExtendSelectionLeftKeyShiftLeftExtendSelectionRightKeyShiftRightExtendSelectionUpKeyShiftUpFindKeyCtrlFHelpKeyF1HwndTarget_HardwareNotSupportDueToProtocolMismatchDue to protocol mismatch hardware support is not available.MoveDownKeyDownMoveFocusBackKeyCtrlLeftMoveFocusDownKeyCtrlDownMoveFocusForwardKeyCtrlRightMoveFocusPageDownKeyCtrlPageDownMoveFocusPageUpKeyCtrlPageUpMoveFocusUpKeyCtrlUpMoveLeftKeyLeftMoveRightKeyRightMoveToEndKeyEndMoveToHomeKeyHomeMoveToPageDownKeyPageDownMoveToPageUpKeyPageUpMoveUpKeyUpNewKeyCtrlNOpenKeyCtrlOPasteKeyCtrlV;ShiftInsertPrintKeyCtrlPPrintPreviewKeyCtrlF2PropertiesKeyF4RedoKeyCtrlYReplaceKeyCtrlHSaveKeyCtrlSScrollPageDownKeyPageDownScrollPageUpKeyPageUpSelectAllKeyCtrlASelectToEndKeyShiftEndSelectToHomeKeyShiftHomeSelectToPageDownKeyShiftPageDownSelectToPageUpKeyShiftPageUpStopKeyEscUndoKeyCtrlZ3.2 快捷键常量的底层消费链路ApplicationCommands文件 ApplicationCommands.cs 定义了命令 ID 枚举CommandIdCut/Copy/Paste/Undo/Redo/Delete/Find/Replace/Help/SelectAll/New/Open/Save/Print/PrintPreview/Properties/ContextMenu/Stop 等见 第 453-481 行并在QueryDefaultGestures中通过KeyGesture.AddGesturesFromResourceStrings(常量键值, SR.XXXKeyDisplayString, gestures)为每条命令注册默认键位如 第 394-398 行 的 ContextMenu 分支。常量字段本身定义于文件末尾的#region Private Fields如 第 486 行 的private const string ContextMenuKey ShiftF10;Apps;。NavigationCommands文件 NavigationCommands.cs 以相同模式消费BrowseBackKey等导航命令键位第 224-225 行常量定义于 第 376 行。值格式说明AltLeft;Backspace这类分号分隔的多手势字符串由KeyGesture.AddGesturesFromResourceStrings解析——分号将字符串拆分为多个独立的KeyGesture即BrowseBack命令默认同时绑定AltLeft与Backspace两个手势。3.3 硬件错误消息的消费位置HwndTarget_HardwareNotSupportDueToProtocolMismatchDue to protocol mismatch hardware support is not available.在 HwndTarget.cs 中以throw new InvalidOperationException(SR.HwndTarget_HardwareNotSupportDueToProtocolMismatch)的形式抛出——这是硬件加速渲染在通道协议不匹配时例如远程桌面/兼容性场景的运行时异常消息本质是面向开发者的诊断文本本地化优先级极低因此一并常量化。四、PresentationFramework文本编辑命令键位与界面格式串常量化PresentationFramework源码位于 src/Microsoft.DotNet.Wpf/src/PresentationFramework迁移内容最丰富文本编辑RichTextBox 等控件的段落/表格/选择/移动等编辑命令键位、InkCanvas与ListBox的全局快捷键以及少量格式化字符串。4.1 完整迁移清单ResourceIDValue常量值InkCanvasDeselectKeyEscKeyAlignCenterCtrlEKeyAlignLeftCtrlLKeyAlignRightCtrlRKeyAltUndoAltBackspaceKeyApplyDoubleSpaceCtrl2KeyApplyOneAndAHalfSpaceCtrl5KeyApplySingleSpaceCtrl1KeyBackspaceBackspaceKeyCopyCtrlCKeyCopyFormatCtrlShiftCKeyCtrlInsertCtrlInsertKeyCutCtrlXKeyDecreaseFontSizeCtrlOemOpenBracketsKeyDecreaseIndentationCtrlShiftTKeyDeleteDeleteKeyDeleteColumnsAltCtrlShiftDKeyDeleteNextWordCtrlDeleteKeyDeletePreviousWordCtrlBackspaceKeyEnterLineBreakShiftEnterKeyEnterParagraphBreakEnterKeyIncreaseFontSizeCtrlOemCloseBracketsKeyInsertColumnsAltCtrlShiftCKeyInsertRowsAltCtrlShiftRKeyInsertTableAltCtrlShiftTKeyMergeCellsAltCtrlShiftMKeyMoveDownByLineDownKeyMoveDownByPagePageDownKeyMoveDownByParagraphCtrlDownKeyMoveLeftByCharacterLeftKeyMoveLeftByWordCtrlLeftKeyMoveRightByCharacterRightKeyMoveRightByWordCtrlRightKeyMoveToColumnEndAltPageDownKeyMoveToColumnStartAltPageUpKeyMoveToDocumentEndCtrlEndKeyMoveToDocumentStartCtrlHomeKeyMoveToLineEndEndKeyMoveToLineStartHomeKeyMoveToWindowBottomAltCtrlPageDownKeyMoveToWindowTopAltCtrlPageUpKeyMoveUpByLineUpKeyMoveUpByPagePageUpKeyMoveUpByParagraphCtrlUpKeyPasteFormatCtrlShiftVKeyRedoCtrlYKeyRemoveListMarkersCtrlShiftRKeyResetFormatCtrlSpaceKeySelectDownByLineShiftDownKeySelectDownByPageShiftPageDownKeySelectDownByParagraphCtrlShiftDownKeySelectLeftByCharacterShiftLeftKeySelectLeftByWordCtrlShiftLeftKeySelectRightByCharacterShiftRightKeySelectRightByWordCtrlShiftRightKeySelectToColumnEndAltShiftPageDownKeySelectToColumnStartAltShiftPageUpKeySelectToDocumentEndCtrlShiftEndKeySelectToDocumentStartCtrlShiftHomeKeySelectToLineEndShiftEndKeySelectToLineStartShiftHomeKeySelectToWindowBottomAltCtrlShiftPageDownKeySelectToWindowTopAltCtrlShiftPageUpKeySelectUpByLineShiftUpKeySelectUpByPageShiftPageUpKeySelectUpByParagraphCtrlShiftUpKeyShiftBackspaceShiftBackspaceKeyShiftDeleteShiftDeleteKeyShiftInsertShiftInsertKeyShiftSpaceShiftSpaceKeySpaceSpaceKeySplitCellAltCtrlShiftSKeySwitchViewingModeCtrlMKeyTabBackwardShiftTabKeyTabForwardTabKeyToggleBulletsCtrlShiftLKeyToggleInsertInsertKeyToggleNumberingCtrlShiftNKeyToggleSubscriptCtrlOemPlusKeyToggleSuperscriptCtrlShiftOemPlusKeyToggleUnderlineCtrlUKeyUndoCtrlZListBoxSelectAllKeyCtrlASwitchViewingMode_Switch ViewingModeToStringFormatString_Control{0}: {1}ToStringFormatString_GridView{0} Columns.Count:{1}ZoomPercentageConverterStringFormat{0:0.##}%4.2 文本编辑命令的注册链路源码佐证文本编辑命令的键位常量集中在System.Windows.Documents命名空间下以TextEditorParagraphs等内部静态类为载体TextEditorParagraphs.cs 在_RegisterClassHandlers中为 RichTextBox 等富文本控件注册编辑命令例如EditingCommands.AlignLeft通过CommandHelpers.RegisterCommandHandler(..., KeyGesture.CreateFromResourceStrings(KeyAlignLeft, nameof(SR.KeyAlignLeftDisplayString)))绑定CtrlLKeyAlignCenterCtrlE、KeyApplySingleSpaceCtrl1等同理常量字段见 第 181-187 行。文本编辑核心 TextEditor.cs 中同样定义了private const string KeyUndo CtrlZ等常量供撤销/重做等命令的默认手势使用。注意区分两类键表内Key*系列如KeyMoveDownByLine Down是编辑命令EditingCommands的默认键位而 PresentationCore 中的MoveDownKey是应用级命令ApplicationCommands/NavigationCommands的键位。二者同名异义迁移时不可混淆。4.3 非快捷键资源说明表中最后 4 项不属于键位SwitchViewingMode _Switch ViewingMode带_下划线的UI 菜单文本下划线表示助记键/快捷键前缀ToStringFormatString_Control {0}: {1}、ToStringFormatString_GridView {0} Columns.Count:{1}调试用 ToString 格式化串不面向最终用户ZoomPercentageConverterStringFormat {0:0.##}%缩放百分比转换格式串用于文档查看器如 FlowDocumentPageViewer的缩放显示。这些字符串格式化模板与快捷键一样属于不需要翻译的资源因此同样被移出 resx 翻译流程。五、迁移后的本地化工作流常量字符串与 resx 的职责分工迁移完成后WPF 的资源系统形成清晰分工资源类别存放位置示例是否参与本地化xlf内部标识/契约串任务名、命令名C#const stringMarkupCompilePass1、FileClassifier否命令默认键位KeyGesture 串C#const stringCtrlC;CtrlInsert、AltLeft;Backspace否运行时异常/诊断消息C#const string或SRHwndTarget_HardwareNotSupportDueToProtocolMismatch否面向用户的显示文本含DisplayString后缀Strings.resxxlf/*.xlfSR.CopyKeyDisplayString、SR.KeyAlignLeftDisplayString是5.1 键位常量与显示文本的解耦模式从源码消费方式可以观察到一套双份资源模式键位值本身作为const string内联供KeyGesture解析而面向屏幕阅读器/无障碍或用户界面的显示描述仍保留在Strings.resx中例如Strings.resx 中的BrowseBackKeyDisplayStringExceptionStringTable.txt 中的BrowseBackKeyDisplayStringAltLeft;Backspacexlf 翻译文件如 Strings.cs.xlf中的BrowseBackKeyDisplayString翻译单元。调用侧代码KeyGesture.AddGesturesFromResourceStrings(常量键值, SR.XXXKeyDisplayString, gestures)的两个参数正是这一分工的体现第一个参数是机器可解析的键位契约常量第二个参数是人可读的显示文本本地化资源。5.2 对贡献者/本地化者的实践建议新增编辑/应用命令快捷键时将键位串定义为private const string XXXKey ...并在命令注册处通过KeyGesture.CreateFromResourceStrings/AddGesturesFromResourceStrings消费若该命令需要可读的显示名称才在Strings.resx中添加XXXKeyDisplayString条目并同步各语言的 xlf 文件。不要为纯内部标识添加 xlf 翻译单元任务名如ResourcesGenerator、调试格式串如{0:0.##}%属于永远不需要翻译的资源应保持常量化否则会产生未翻译字符串untranslated strings噪音并拖慢本地化流程。查询某常量在哪被使用可沿const string KeyUndo CtrlZ这类定义反查引用点或在TextEditor*.cs、ApplicationCommands.cs、NavigationCommands.cs、HwndTarget.cs中搜索对应资源名跨语言本地化工作由 PresentationCore/Resources/xlf、PresentationFramework/Resources/xlf 等目录中的.xlf文件承接。六、总结本仓库的本地化资源重构将非本地化的 ResourceID 统一收敛为 C# 常量字符串与代码一起编译、裁剪、维护PresentationBuildTasks8 项MSBuild 构建任务名契约串无需翻译PresentationCore约 41 项应用/导航命令默认键位 1 条硬件协议错误消息PresentationFramework90 余项富文本编辑命令键位、InkCanvas/ListBox 快捷键及调试格式串。这一改动让strings.resx只保留真正需要翻译的用户可见文本从源头消除了未翻译字符串噪音同时让键位契约在源码中可静态检索、可被编译器优化——理解这套分工模式是在 WPF 仓库中正确维护命令系统与本地化资源的前提。赞分享桌面应用前端UI组件【免费下载链接】wpfWPF is a .NET Core UI framework for building Windows desktop applications.项目地址https://gitcode.com/gh_mirrors/wp/wpf点击查看免费下载相关推荐Valdi 国际化Localization实战指南从 strings-en.json 到全平台本地化字符串Valdi 国际化Localization实战指南从 strings en.json 到全平台本地化字符串 Valdi 提供了一套与构建系统深度集成的本地跨平台UI组件前端移动开发numpy.char 遗留定宽字符串操作模块完全指南向量化字符串 API、比较语义与 chararray 弃用迁移numpy.char 遗留定宽字符串操作模块完全指南向量化字符串 API、比较语义与 chararray 弃用迁移 本文是 NumPy 官方参考文档 doc/科学计算数据分析Kronos用AI语言模型重新定义金融时序预测Kronos用AI语言模型重新定义金融时序预测 想象一下当传统量化模型在2024年科技股财报季集体失灵时一个基于Transformer架构的金融基础模人工智能大模型基础模型预训练金融科技上一篇终极指南DalmatinerDB写入优化策略与最佳实践下一篇一文读懂KnowledgeEditingPapersLLM知识编辑的核心方法与前沿技术对比创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表