目录

要使一个窗体(Form)支持本地化,需要付出一定量的努力。用于本地化控件的努力很小,而且只需做一次。代码中内嵌的文本字符串需要以特定方式处理,但只有需要本地化的字符串才需要这样处理。仅使用异常对象或 exception.message 属性来显示错误的 Try…Catch 结构,会根据操作系统的语言设置自动显示。任何不打算让用户去解读的应用程序错误都应保留英文,这样当用户把错误报告给我们时,开发团队就不必做额外的工作去弄清该错误究竟是什么。

附加属性

以下属性需要添加到任何要支持本地化的窗体中:

Property ToolTipText(c As Control) As String Get ToolTipText = Me.ToolTip1.GetToolTip(c) End Get Set(Value As String) ToolTip1.SetToolTip(c, Value) End Set End Property

该属性为任何不直接支持工具提示(ToolTip)属性的控件返回并设置 ToolTipText(实际上几乎除菜单项(MenuItems)之外的所有控件都是如此)。请注意,窗体上启用这些功能的 ToolTip 组件必须命名为 ToolTip1,否则必须把上面的代码改为正确的名称。如果窗体上没有编写任何工具提示,则完全省略该属性例程。

Property Msg(keyy As String) As String Get Try 'Debug.Print(keyy) If Microsoft.VisualBasic.Strings.Left(keyy, 1) = ChrW(157) Then keyy = Strings.Right(keyy, Len(keyy) - 1) End If Msg = dict(keyy).ToString Catch Msg = "Invalid key - " & keyy & " - is missing from translation dictionary. Please contact the development team." End Try End Get Set(Value As String) dict(keyy) = Value End Set End Property

ReadOnly Property GetMsgDict() As Dictionary(Of String, String) Get GetMsgDict = dict End Get End Property

这些属性支持对内联消息进行字符串查找和替换,例如任何要送往 MsgBox 或 StatusStrip 的内容。变量 dict 是一个字典,其结构和用途将在下文说明。

附加事件

Private Sub Station_LanguageChanged() Handles stn.LanguageChanged Call SetLocalStrings(Me, True) End Sub

如果在配置器(Configurer)窗体中更改了语言,这将使该窗体以新语言重新绘制。

注意:调用 SetLocalStrings 时的可选参数(上例中为 True)用于在调用时强制把字符串转换为英文。通常,如果所选语言是英文(默认值),该例程不再做其他事,而是立即返回。如果语言从非英文改回英文,则该例程必须在数据库中查找英文字符串并使用它们,事件处理程序才能做任何有意义的事。否则,需要关闭并重新打开应用程序,才能以英文重新显示。

必需调用

将以下调用添加到窗体加载事件中:

Call SetLocalStrings(Me)

支持的控件

本地化代码目前支持以下控件。

  • Label – Text 属性与 ToolTip 属性(若存在)
  • CheckBox – Text 属性与 ToolTip 属性(若存在)
  • RadioButton – Text 属性与 ToolTip 属性(若存在)
  • Button – Text 属性与 ToolTip 属性(若存在)
  • ListView – ColumnHeaders 的 Text 属性
  • GroupBox – Text 属性及所有子控件
  • GroupBoxEx – Text 属性及所有子控件
  • TableLayoutPanel – Text 属性及所有子控件
  • Panel – Text 属性及所有子控件
  • TabControl – 所有子控件,包括选项卡页(Tab Pages)
  • StatusStrip – 所有 ToolStripStatusLabels 子控件
  • MenuStrip(及其子对象,即菜单项(MenuItems))– Text 与 ToolTip 属性
  • N1MMNumericUpDown – 忽略(不显示“Object not handled yet”消息)
  • AxN1MMWave – 忽略(不显示“Object not handled yet”消息)
  • ComboBox – ToolTipText 属性(若存在)
  • TextBox – ToolTipText 属性(若存在)
  • RichTextBox – ToolTipText 属性(若存在)
  • PictureBox – ToolTipText 属性(若存在)
  • NumericUpDown – ToolTipText 属性(若存在)
  • HScrollBar – ToolTipText 属性(若存在)
  • DateTimePicker – 忽略,没有要设置的属性
  • ListBox – 忽略,没有要设置的属性
  • TrackBar – 忽略,没有要设置的属性
  • AxXMMVView – 忽略,没有要设置的属性
  • AxXMMVLvl – 忽略,没有要设置的属性
  • DataGridView – 列标题文本与工具提示。注意,目前只能翻译预定义的静态列标题文本。动态设置的文本元素可通过字典实现。
  • AxXMMVBtn – Text 属性

以下控件存在于 N1MM+ 中,但目前不受支持:

  • ShapeContainer
  • SplitContainer
  • Chart

注意,许多控件是其他元素的容器。选项卡页(TabPages)就是一个明显的例子。某些控件(如 ListView)没有可直接设置的文本元素属性,但其子级(例如列标题)有。在这些情况下,会为该控件建立一条数据库记录,并把文本值字段留空。该条目的用途是通过 Parent 数据库字段维护修改子级所需的控件层级。

字典

为了实现内联字符串的翻译,在要启用翻译的每个窗体中都会创建一个字典。该字典只需保存待翻译字符串的英文占位符。我编写了一个工具来提取字符串、创建关联的编译时字典声明,并在要启用的字符串语句中插入适当的引用。这对我有效,YMMV。首次为一个大型窗体启用翻译可能很繁琐。一旦加入了字典,添加新字符串所需的工作就相当微不足道了。

再次强调,要记住帕累托原则(Pareto Principle),不要在这上面走火入魔。我大多把录入窗口(EntryWindow)的 MsgBox 标题(若存在)保留为英文,这样如果翻译后由用户报告给开发团队,就更容易识别出具体的错误消息。如果你决定不允许翻译这些字符串,可以完全跳过它(连同上面的相关属性)。

N1MM Logger+ 手册(中文版) / 翻译技术信息(面向开发者) 0 字 0 行 bg8lng
2026-10-08T12:08:00.112567067Z 2026-10-08T12:45:02.769858405Z