将所有控件值保存和加载到用户设置






4.94/5 (17投票s)
本文提供了一个程序,演示如何将所有控件的值保存到用户设置中,以及如何从用户设置中加载它们。
引言
当应用程序将最后输入的数值保存到用户设置中时,非常方便,这样用户在重新启动时就不必重复输入相同的内容。当保存以下内容时也同样方便:网格的列宽、分割器的位置、工具栏的位置和可见性、窗口的大小和位置。本程序演示了如何做到这一点,以及如何将设置导出到文件或从文件导入设置。
背景
NET Framework 通过 `System.Configuration.ApplicationSettingsBase` 类提供了一种简单的方法来存储和加载用户设置。最简单的方法是使用 Visual Studio 定义用户设置变量。每个项目都在“我的项目”文件夹中有“Settings.settings
”项。双击此项,会出现一个页面,您可以在其中定义可保存到用户设置的变量。例如,此图显示已定义了类型为 `String` 的变量“ControlValues
”
在代码中,可以通过 `My.Settings.ControlValues` 访问此变量。可以为此变量设置一个值,例如
My.Settings.ControlValues = "abcd"
并且可以检索此变量的值,例如
Dim s As String = My.Settings.ControlValues
可以通过以下方式将这些变量保存到用户设置中:
My.Settings.Save()
通常,开发人员会为要保存到用户设置中的每个控件值创建一个设置变量。加载窗体时,这些变量将被分配给控件值;关闭窗体时,控件值将被分配给这些变量,然后保存设置。例如,如果窗体中有三个 `TextBox`,典型代码如下所示:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
TextBox1.Text = My.Settings.TextBox1
TextBox2.Text = My.Settings.TextBox2
TextBox3.Text = My.Settings.TextBox3
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
My.Settings.TextBox1 = TextBox1.Text
My.Settings.TextBox2 = TextBox2.Text
My.Settings.TextBox3 = TextBox3.Text
My.Settings.Save()
End Sub
当控件很多时,此代码会变得相当庞大,并且在添加或删除控件时必须进行修改。本程序提供了以下重写上述代码的功能:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SetControlValues(Me, My.Settings.ControlValues)
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
My.Settings.ControlValues = GetControlValues(Me, mExludeControlSettings)
My.Settings.Save()
End Sub
代码更小,并且具有不随添加或删除控件而修改的优点。所有控件值都以 XML 形式写入一个设置变量。无需添加和删除设置变量。此外,还提供了一种简便的方法,可以将控件值导出到文件或从文件导入,并可以将控件值重置为初始值。
Using the Code
此程序可以将窗体所有控件的所有值保存到用户设置变量 `My.Settings.ControlValues` 中。它还可以从此变量中检索所有控件值。
要运行该程序,请执行以下步骤:
- 使用 Visual Studio 2010,打开项目 Tests.UI.vbproj。
- 构建解决方案。
- 在调试器中或使用可执行文件 Tests.UI\Debug\bin\Tests.UI.exe 启动 `Tests.UI`。将出现以下窗体:
- 修改第一个选项卡页面中所有控件的值。第一个 `combobox` 的行为类似于普通的 `combobox`,第二个 `combobox` 的行为类似于带历史记录的 `textbox`。这意味着,每次焦点移出第二个 `combobox` 时,`combobox` 中显示的文本都会添加到 `combobox` 的项中。最多保留 10 个不同的项。
- 在第二个选项卡页面中,在网格中输入值,修改 `DataGridView1` 中的列宽,更改属性网格中的值,移动分割器位置,并更改窗体的大小。
- 通过第一个工具栏上的上下文菜单修改工具栏的位置和可见性。
- 关闭窗体。控件值应已保存到用户设置中。
- 重新启动 `Tests.UI`。所有控件值都应采用您之前输入的值。
- 在 `TabPage3` 中,单击“导出”按钮。
- 将出现一个对话框,选择应导出控件值到的文件,然后单击“确定”。
- 单击“重置”按钮。
- 查看前两个选项卡页面,控件现在已填充初始值。
- 在 `TabPage3` 中,单击“导入”按钮。
- 选择您在导出时选择的文件,然后单击“确定”。
- 查看前两个选项卡页面,控件现在已填充在导出之前的值。
- 在 zip 文件中提供了一个设置文件 (Settings1.xml)。您也可以尝试加载此文件。
Module1
此模块提供四个 `public` 方法:
GetControlValues
接收一个窗体和一个要排除的控件列表作为参数,并返回一个 `string`。该函数遍历窗体的所有控件,创建一个 `XmlDocument`,其中包含除要排除列表中的控件之外的所有控件值。用户可以修改的内容都包含在内,例如,`TextBox` 的文本、`DataGridView` 的底层 `DataSet`、`DataGridView` 的列宽、`PropertyGrid` 中的值、`SplitContainer` 中分割器的位置、`TrackBar` 的值,甚至窗体的大小和位置。生成的 `XmlDocument` 以 `string` 的形式返回。
SetControlValues
接收一个 `form` 和包含 `XmlDocument` 的 `string` 作为参数。该方法遍历 `XmlDocument` 中的所有节点,并更新相应控件中的值,但不包括列表控件 `CheckedListBox`、`ComboBox` 和 `ListBox`。对于这些控件,值会被复制到它们的 `Tag` 属性中。这些控件的项可以动态加载,例如从数据库加载,然后可以使用 `CopyControlValuesFromTag` 方法将值从 `Tag` 属性复制到控件。
CopyControlValuesFromTag
接收一个控件作为参数,并递归地对所有列表控件(`CheckedListBox`、`ComboBox` 和 `ListBox`)执行操作,将值从 `Tag` 属性复制到设置相应的选定和勾选项。例如,`ListBox` 的 `Tag` 属性包含一个逗号分隔的 `SelectedIndices` 列表,当 `SetControlValues()` 完成时。此方法获取逗号分隔的列表,并选择相应的项。
ComboboxSetTextBoxWithHistory
接收多个 `combobox`(`ParamArray`)作为参数,并使它们像带历史记录的 `textbox` 一样工作。这意味着 `Tag` 属性设置为“TextBoxWithHistory
”,并向 `LostFocus` 事件添加一个处理程序。此处理程序将当前 `combobox` 中显示的文本添加到 `combobox` 的项中。最近使用的项位于顶部。对于这些 `combobox`,选定的值以及项(历史记录)会被保存到用户设置中并从中加载。`SetControlValues` 方法会为这些 combobox 设置 `Text` 属性,而对于普通 combobox 则设置 `Tag` 属性。因此,`CopyControlValuesFromTag` 方法会忽略这些 `combobox`。
ToolStripAddContextMenus
接收一个 `ToolStrip` 作为参数。该方法将菜单项添加到 `ToolStrip` 的 `ContextMenuStrip` 中。为 `ToolStripContainer` 中的所有 `ToolStrip` 添加菜单项,但要排除给定的 `ToolStrip`。在提供的代码中,有 3 个 `ToolStrip`(`ToolStrip1` 到 `3`)。`ToolStrip1` 是主 `ToolStrip`,不能设置为隐藏。在 `ToolStrip1` 上有一个上下文菜单。此方法为 `ToolStrip2` 和 `ToolStrip3` 中的每一个添加一个菜单项。通过取消选中菜单项上的复选框,相应的 `ToolStrip` 将变得不可见;通过选中菜单项,相应的 `ToolStrip` 将再次变得可见。
Form1
前两个选项卡包含每种可能的 Windows 窗体控件的一个控件,以演示控件值的保存和加载。第三个选项卡提供了用于导出、导入和重置控件值的按钮。窗体底部的 `textbox TextBoxLog` 用于写入日志消息。成员变量 `mExludeControlSettings` 包含所有不应保存到用户设置中的控件,在这种情况下,它只包含 `TextBoxLog`。通常,`mExcludeControlSettings` 会包含显示来自数据库的数据的 `DataGridView` 和 `DataGrid`。对于 `DataGridView`,即使它们被排除,列宽也会被存储到用户设置中。
新建
在窗体的构造函数中,有以下语句:
-
mExludeControlSettings = {TextBoxLog}
成员变量 `mExludeControlSettings` 包含所有应从用户设置的保存和加载中排除的控件。这些控件通常是编写日志的控件,或者显示来自数据库数据的网格。 -
mTestObject1 = New TestObject
这只是一个要显示在属性网格中的测试对象。 -
PropertyGrid1.SelectedObject = mTestObject1
指定属性网格应显示哪个对象。 -
ComboboxSetTextBoxWithHistory(ComboBox2)
此方法定义了所有要作为带历史记录的 `textbox` 使用的 `combobox`。
Form1_Load
加载窗体后,将执行以下语句:
-
mOriginalSettings = GetControlValues(Me, mExludeControlSettings)
所有初始值都设置为成员变量 `mOriginalSettings`。此变量稍后可用于重置控件值。 -
If My.Settings.ControlValues <> "" Then SetControlValues(Me, My.Settings.ControlValues)
如果用户设置不为空,则从用户设置加载控件值。对于列表控件(`CheckedListBox`、`ComboBox` 和 `ListBox`),值将加载到它们的 `Tag` 属性中。 -
CheckedListBox1Fill, ComboBox1Fill, Listbox1Fill
列表控件的项已填充。在这种情况下,它们用枚举类型的值填充,但在现实世界中,它们可以从数据库填充。 -
CopyControlValuesFromTag(Me)
从列表控件的 `Tag` 属性获取值,并设置相应的选定和勾选项。 -
ToolStripManager.LoadSettings(Me)
这是 .NET Framework 提供的一个用于加载工具栏位置和可见性的方法。 -
ToolStripAddContextMenus(ToolStrip1)
此方法为 `ToolStrip1` 中的每个其他工具栏(`ToolStrip2` 和 `ToolStrip3`)添加上下文菜单。`ToolStrip1` 不能隐藏,因此不为 `ToolStrip1` 添加上下文菜单。上下文菜单会检查相应的工具栏是否可见。
Form1_FormClosing
关闭窗体后,将执行以下语句:
-
My.Settings.ControlValues = GetControlValues(Me, mExludeControlSettings)
所有当前控件值都存储到用户设置变量中。 -
My.Settings.Save()
用户设置通常保存在 C:\Documents and Settings 文件夹中的文件中。 -
ToolStripManager.SaveSettings(Me)
这是 .NET Framework 提供的一个用于保存工具栏位置和可见性的方法。
ButtonSettingsExport_Click
显示一个选择文件的对话框,然后通过以下方式将控件值写入文件:
Dim s As String = GetControlValues(Me, mExludeControlSettings)
File.WriteAllText(d.FileName, s)
ButtonSettingsImport_Click
显示一个选择文件的对话框,然后通过以下方式将控件值从文件读取:
Dim s As String = File.ReadAllText(d.FileName)
SetControlValues(Me, s)
CopyControlValuesFromTag(Me)
ButtonSettingsReset_Click
通过以下方式将所有控件的所有值设置为其初始值:
SetControlValues(Me, mOriginalSettings)
CopyControlValuesFromTag(Me)
变量 `mOriginalSettings` 包含控件的初始值,即在应用用户设置之前的值。
历史
- 将控件值保存和加载到 XML,并将 XML 保存到用户设置中。
- 保存和加载工具栏位置和可见性。
- 分两阶段加载列表控件,`combobox` 像带历史记录的 `textbox` 一样,保存 `PropertyGrid`。
- 修改了 `GetControlValue`s,以便排除参数可以为空。
- 修正了 `MaskedTextBox` 和 MDI 客户端。