65.9K
CodeProject 正在变化。 阅读更多。
Home

设置/选项对话框 2005

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (17投票s)

2005年11月15日

CPOL

6分钟阅读

viewsIcon

142808

downloadIcon

1433

从 My.Settings 命名空间中创建的设置生成一个选项对话框。

引言

我想创建一个简单的方法来设置一个设置(选项)对话框,类似于 Visual Studio 在您转到“工具”>“选项”时的“选项”框。我希望包含一些要求,例如可重用性、处理多种数据类型、类别、排序以及名称中的空格。有关本文中所述代码的完整解释,请下载源代码并阅读注释。每个函数/子程序都已完全注释,并且每个函数/子程序都有新的 XML 注释(VB 新增),(控件处理程序上没有 XML 注释)。

2005 年 12 月 12 日 - 我要感谢 Peter Spiegler 发送给我用于支持系统定义的枚举的代码。

设置

这个对话框最棒的部分在于它读取 My.Settings 命名空间中的所有设置,这意味着您可以直接从 IDE 设计器创建/编辑默认设置。您可以通过转到“项目”>“{项目名称} 属性...”然后转到“设置”页面来执行此操作。

为了让您的设置显示在对话框中,我们对其施加了一些规则:

  1. 名称中必须包含下划线。
  2. 数据类型必须受支持(有关支持的数据类型列表,请参见下文)。
  3. 设置必须是 UserScoped(用户范围)。

下划线是必需的,这样它就可以将您的设置的实际名称与您希望放入的类别分开。请参阅下面的截图了解一些示例。

您会注意到截图中的几个设置名称中有双下划线。这是为了允许在类别名称或设置名称本身中使用空格。您还会注意到截图中的所有名称后面都有一个数字。这是为了在同一类别内对设置进行排序。该设置必须具有用户范围,而不是应用程序范围。当设置具有应用程序范围时,它在运行时是只读的,由于我们希望在运行时更改这些设置,因此它必须具有用户范围。

IDE 的设置设计器支持多种数据类型,但支持 TimeSpan 或 GUID 等数据类型会更困难一些。虽然 TextBox 可以提供编辑这些数据类型的支持,但我不想干扰验证,而且我发现将它们用作您希望在选项对话框中更改的用户作用域对象的情况很少。支持类型的列表:

  • 字节型
  • Char
  • 十进制
  • 双精度浮点型
  • 整数
  • 长整型
  • SByte
  • Short
  • Single
  • 字符串
  • UInteger
  • ULong
  • UShort
  • 系统定义的枚举(2005 年 12 月 12 日添加)

使用此窗体

使用此窗体与其他窗体的使用方式相同。声明一个它的实例并使用 ShowDialog 方法。有几种不同的样式可供选择 - 有关更多详细信息,请参见下文。

Dim f As New frmOptions
f.Style = frmOptions.OptionsStyle.FireFox2
f.ShowDialog(Me)

样式(2005 年 12 月 12 日)

您可以使用四种不同的样式。TreeView 和 TabPages 并不是什么新鲜事,但自 2005 年 12 月 12 日起,我已加入对 FireFox1 和 FireFox2 的支持。FireFox1 是 FireFox 1.5 版本之前的选项框样式。FireFox2 是 FireFox 1.5 版本的样式。只需更改一行代码 f.Style = frmOptions.OptionsStyle.FireFox2 即可更改对话框的外观。使用 TreeView 样式时要小心,因为它可能会让非技术用户(他们很可能占您用户群的大多数 - 谢谢 Anna)感到困惑。对于 FireFox 样式,您还可以添加图像。目前,这些图像必须是 32x32 才能支持控件的宽度/高度,但您可以随意修改代码以支持其他大小。以下是可下载源代码中的一个示例。

Dim f As New frmOptions
'f.OptionStyle = frmOptions.OptionsStyle.FireFox1
f.Style = frmOptions.OptionsStyle.FireFox2
'f.OptionStyle = frmOptions.OptionsStyle.TabPages
'f.OptionStyle = frmOptions.OptionsStyle.TreeView
f.ImageAdd("Database", My.Resources.database)
f.ImageAdd("Misc", My.Resources.ClockFace)
f.ImageAdd("Fonts", My.Resources.fonts)
f.ImageAdd("Colors", My.Resources.circles)
f.ImageAdd("COM", My.Resources.rotary_phone)
f.ShowDialog(Me)

ImageAdd 允许您添加图像。我在这里将所有图像都加载为资源,以便轻松引用它们。添加每个图像时,您必须指定每个图像所属的主要组,否则它们将不会显示。

树视图

TabPages

FireFox1

FireFox2

窗体

窗体相对简单。我有一个固定在左侧的 TreeView 和一个固定在右侧的 TableLayoutPanel。它们用作设置的容器。关于 TreeView 的一个注意事项是,路径分隔符是句点。还有一个复选框,供用户选择是否要在应用程序退出时保存其设置,以及标准的“确定”、“取消”和“应用”对话框按钮。

加载设置

为了能够更改设置但不应用它们(因此才有应用和确定按钮),我们需要有一个存储所有设置信息的空间。因此,我创建了一个带有集合的类来为我们存储这些信息 - SettingInfo 和 SettingInfoCollection。每个 SettingInfo 对象都需要存储 Name、Category、SortIndex 和 Value。该类中有一个子程序,当调用该子程序并传入真实的设置名称(您在设计器中看到的名称)时,它会加载所有这些信息。该集合应向我们返回给定类别的所有设置,并更改给定索引或真实名称的值(甚至是一个完整的项目以用于排序)。

在窗体的 Load 事件中,我们需要加载所有可用的设置。为此,我们需要遍历 My.Settings.Properties 中的每个 SettingsProperty,并将每个设置添加到集合中。

'Load the SaveOnExit value
chkSaveOnExit.Checked = My.Application.SaveMySettingsOnExit
'Setup the Setting property object for grabing all the settings
Dim sp As System.Configuration.SettingsProperty = Nothing

'Cycle through each setting and add it if appropriate.
For Each sp In My.Settings.Properties
    'If the name doesn't have an underscore - we can't 
    'assign a category so we can't change it.
    'If the setting is ApplicationScoped - we aren't 
    'able to hange it at runtime.
    'Check also if there is support on this form for 
    'the System.Type the setting is.
    If sp.Name.IndexOf("_") <> -1 AndAlso _
           IsUserScope(sp) AndAlso IsAllowedType(sp) Then
        'Passed the tests create a new SettingInfo object
        Dim newSetting As New SettingInfo
        'Load the settings data into the object
        newSetting.LoadData(sp.Name)
        'Add the object to the collection
        Settings.Add(newSetting)
    End If
Next

'Sort the settings by category - makes the 
'TreeView look nice
quickSort(Settings)
'Load the settings into the TreeView
LoadTreeView()

要将类别加载到 TreeView 中(请参阅 LoadTreeView() 方法),我有一个函数可以将类别/子类别从数组中添加。

显示编辑控件

在 TreeView 中选择一个类别后(当您首次显示窗体时应该会发生此情况),需要显示控件。由于节点具有 FullPath 属性,因此 TreeView 是显示类别的理想控件。因此,为了获取选定类别的所有设置,我们只需使用类中提供的函数。

'Get all the settings that match this category
Dim sets() As SettingInfo = _
  Settings.GetByCategory(tvCategories.SelectedNode.FullPath)

从这里,我遍历所有返回给我的设置,并确定用于编辑的适当控件,向每个控件的 LostFocus 事件添加处理程序,以更新集合中存储的值。

应用设置

应用设置非常简单 - 只需遍历集合中的每个设置,并更新 My.Settings 命名空间中存储的值。

'Cycle through each setting that we could edit and
'update the real setting contained in the My namespace
For Each si As SettingInfo In Settings
    My.Settings.Item(si.TrueName) = si.Value
Next
'Update the SaveOnExit value
My.Application.SaveMySettingsOnExit = chkSaveOnExit.Checked

单击“确定”或“应用”按钮将触发上述代码。“应用”不会关闭对话框。“确定”将 DialogResult 设置为 OK,它是窗体的接受按钮。“取消”是窗体的取消按钮,并将 DialogResult 设置为 CANCEL。

在运行时,如果您取消选中退出时保存设置的复选框,设置在您更改它们时将正确应用,但在您重新启动应用程序后,它们将再次恢复为默认值。保留选中状态将确保您更改的设置将在程序的下一次运行中保留。

结论

我真的很讨厌写结论。我将让您,读者,自己得出关于这段代码的结论。我希望您觉得它有用且易于使用。

© . All rights reserved.