Introduction
It is convenient when applications save the last entered values to the user settings, so that on restart, the user does not have to retype the same things. It is also convenient, when the following items are saved: column widths of a grid, the position of a splitter, positions and visibility of toolbars, the size and location of the window. This program demonstrates how to do this, and also how to export and import the settings to and from a file.
Background
The .NET Framework provides an easy way to store and load user settings through the System.Configuration.ApplicationSettingsBase
class. The easiest way is to define user settings variables with Visual Studio. Every project has in the "My Project" folder the item "Settings.settings
". By double-clicking on this item, a page appears, where variables may be defined, that have the capability to be saved to the user settings. For example, this figure shows that the variable "ControlValues
" of type String
is defined:
In code, this variable may be accessed through My.Settings.ControlValues
. A value may be set to this variable, for example:
My.Settings.ControlValues = "abcd"
And this variable's value may be retrieved, for example:
Dim s As String = My.Settings.ControlValues
These variables may be saved to the user settings through:
My.Settings.Save()
Usually, developers create a setting variable for every control value that is to be saved to user settings. On loading the form, these variables are assigned to control values, and on closing the form, the control values are assigned to these variables and the settings are saved. For example, if there are three TextBox
es in a form, the typical code looks as follows:
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
When there are a lot of controls, this code gets quite large, and must be modified when adding or removing controls. This program provides the functionality to rewrite the above code as follows:
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
The code is smaller and has the advantage that it has not to be modified when adding or removing controls. All control values are written as XML to only one setting variable. There is no need to add and remove setting variables. In addition, there is an easy way to export and import control values to and from a file, and to reset control values to their initial values.
Using the Code
This program can save all values of all controls of the form to the user settings variable My.Settings.ControlValues
. It can also retrieve all control values from this variable.
To run the program, follow these steps:
- With Visual Studio 2010, open project Tests.UI.vbproj.
- Build the solution.
- Start
Tests.UI
either in the debugger, or with the executable Tests.UI\Debug\bin\Tests.UI.exe. The following form appears:
- Modify values in all controls in the first tab page. The first
combobox
behaves like a normal combobox
, the second combobox
behaves like a textbox
with history. This means, that every time the focus moves out from the second combobox
, the text displayed in the combobox
is added to the combobox
's items. Up to 10 distinct items are kept. - In the second tab page, enter values in the grids, modify column widths in
DataGridView1
, change values in the property grid, move the splitter position, and change the size of the form.
- Modify the position and the visibility of the toolbars through the context menu on the first toolbar:
- Close the form. The control values should be saved to the user settings.
- Restart
Tests.UI
. All control values should take the values you entered before. - In
TabPage3
, click on button Export. - A dialog appears, select a file to which the control values should be exported to and click OK.
- Click on button Reset.
- Look in the first two tab pages, the controls are now filled with initial values.
- In
TabPage3
, click on button Import. - Select the file you selected in the export, and click OK.
- Look in the first two tab pages, the controls are now filled with values they had before the export.
- A settings file (Settings1.xml) is provided in the zip file. You may try to load this file as well.
Module1
This module provides four public
methods:
GetControlValues
Takes as argument a form and a list of controls to be excluded and returns a string
. The function traverses all controls of the form and creates an XmlDocument
containing all control values except those in the list to be excluded. Anything a user may modify is included, for example, the text of the TextBox
es, the underlying DataSet
of a DataGridView
, the column widths of a DataGridView
, the values in the PropertyGrid
, the position of the splitter in a SplitContainer
, the value of a TrackBar
, even the size and position of the form. The resulting XmlDocument
is returned as a string
.
SetControlValues
Takes as argument a form
and a string
containing an XmlDocument
. The method traverses all nodes in the XmlDocument
, and updates the values in the corresponding controls, except the list controls CheckedListBox
, ComboBox
and ListBox
. For these controls, the value is copied to their Tag
property. The items of these controls may then be loaded dynamically, for example from a database, and then the values may be copied from the Tag
property to the control with the method CopyControlValuesFromTag
.
CopyControlValuesFromTag
Takes as argument a control and recursively for all list controls (CheckedListBox
, ComboBox
and ListBox
) takes the value from the Tag
property to set the corresponding selected and checked items. For example, the ListBox
's Tag
property contains a comma separated list of the SelectedIndices
when SetControlValues()
has finished. This method takes the comma separated list, and selects the corresponding items.
ComboboxSetTextBoxWithHistory
Takes as argument a number of combobox
es (ParamArray
), and makes them behave like textbox
es with history. That means, the Tag
property is set to "TextBoxWithHistory
" and a handler is added to the event LostFocus
. This handler adds the current value displayed in the combobox
to the items of the combobox
. The most recently used item is at the top. For these combobox
es, the selected value, as well as the items (the history) are saved to and loaded from the user settings. The method SetControlValues
sets the Text
property for these comboboxes unlike the Tag
property for the normal comboboxes. Consequently, the method CopyControlValuesFromTag
ignores these combobox
es.
ToolStripAddContextMenus
Takes as argument a ToolStrip
. The method adds menu items to the ContextMenuStrip
of the ToolStrip
. A menu item is added for all ToolStrip
s in the ToolStripContainer
except for the given ToolStrip
. In the code provided, there are 3 ToolStrip
s (ToolStrip1
through 3
). ToolStrip1
is the main ToolStrip
and may not be made invisible. On ToolStrip1
, there is a context menu. This method adds a menu item for each of ToolStrip2
and ToolStrip3
. By unchecking the checkbox
on a menu item, the corresponding ToolStrip
becomes invisible, and by checking the menu item, the corresponding ToolStrip
becomes visible again.
Form1
The first two tabs contain one control of each possible Windows form control to demonstrate the saving and loading of control values. The third tab provides buttons to export, import, and reset control values. The textbox TextBoxLog
at the bottom of the form is used to write log messages. The member variable mExludeControlSettings
contains all controls which are not to be saved to the user settings, in this case it contains only TextBoxLog
. Typically, mExcludeControlSettings
will include DataGridView
s and DataGrid
s that display data from a database. In the case of DataGridView
s, even if they are excluded, the column widths are stored into the user settings.
New
In the constructor of the form, there are the following statements:
-
mExludeControlSettings = {TextBoxLog}
The member variable mExludeControlSettings
contains all controls that are to be excluded from saving to and loading from the user settings. These controls are typically controls were logging is written, or grids were data from a database is displayed. -
mTestObject1 = New TestObject
This is just a test object to be displayed in the property grid. -
PropertyGrid1.SelectedObject = mTestObject1
Specifies which object the property grid shall display. -
ComboboxSetTextBoxWithHistory(ComboBox2)
This method defines all the combobox
es that are to behave like textbox
es with history.
Form1_Load
Upon loading the form, the following statements are executed:
-
mOriginalSettings = GetControlValues(Me, mExludeControlSettings)
All initial values are set to the member variable mOriginalSettings
. This variable may later be used to reset the control values. -
If My.Settings.ControlValues <> "" Then SetControlValues(Me, My.Settings.ControlValues)
If the user settings are not empty, then the control values are loaded from the user settings. For list controls (CheckedListBox
es, ComboBox
es and ListBox
es) the values are loaded into their Tag
property. -
CheckedListBox1Fill, ComboBox1Fill, Listbox1Fill
The items of the list controls are filled. In this case, they are filled with values from enumeration types, but in the real world, they could be filled from a database. -
CopyControlValuesFromTag(Me)
Takes the value from the Tag
property of the list controls and sets the corresponding selected and checked items. -
ToolStripManager.LoadSettings(Me)
This is a method provided by the .NET framework to load the position and visibility of the toolbars. -
ToolStripAddContextMenus(ToolStrip1)
This method adds context menus to ToolStrip1
for each of the other toolbars (ToolStrip2
and ToolStrip3
). ToolStrip1
may not be hidden, and therefore no context menu is added for ToolStrip1
. The context menus are checked whether the corresponding toolbar is visible.
Form1_FormClosing
Upon closing the form, the following statements are executed:
-
My.Settings.ControlValues = GetControlValues(Me, mExludeControlSettings)
All current control values are stored to the user settings variable. -
My.Settings.Save()
User settings are saved to a file usually in the folder C:\Documents and Settings. -
ToolStripManager.SaveSettings(Me)
This is a method provided by the .NET framework to save the position and visibility of the toolbars.
ButtonSettingsExport_Click
A dialog box to select a file is shown, and then the control values are written to the file through:
Dim s As String = GetControlValues(Me, mExludeControlSettings)
File.WriteAllText(d.FileName, s)
ButtonSettingsImport_Click
A dialog box to select a file is shown, and then the control values are read from the file through:
Dim s As String = File.ReadAllText(d.FileName)
SetControlValues(Me, s)
CopyControlValuesFromTag(Me)
ButtonSettingsReset_Click
All values of all controls are set to their initial values through:
SetControlValues(Me, mOriginalSettings)
CopyControlValuesFromTag(Me)
The variable mOriginalSettings
contains the values of the controls, as they were initially, before applying the user settings.
History
- Saving and loading of control values to XML, and the XML is saved to user settings
- Saving and loading of toolbar positions and visibility
- Loading of list controls in two phases,
combobox
es like textbox
es with history, saving of PropertyGrid
s - Changed
GetControlValue
s, so that excludes parameter may be nothing - Correction for
MaskedTextBox
and MDI client