Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Settings/Options DialogBox 2005

0.00/5 (No votes)
2 Aug 2013 1  
Generate an Options dialog box from the settings you create in the My.Settings namespace.

Introduction

I wanted to create an easy way to setup a Settings (options) dialog box similar to the Options box of Visual Studio when you go to Tools > Options. There were a few requirements I wanted to include like, reusability, handling many data types, categories, sorting and spaces in the names. For complete explanation of the code described in this article, please download the source code and read the comments. Each function/subroutine is fully commented, as well as has the new XML comments (new for VB) for each one (no XML comments are on control handlers).

12/12/2005 - I'd like to thank Peter Spiegler for sending me the code to support system-defined enumerations.

The settings

The great part about this dialog box is that it reads all the settings from the My.Settings namespace, which means you can create/edit your default settings directly from the IDE designer. You can do this by going to Project > {name} Properties... and then going to the Settings page.

There are a few rules that are imposed on your settings in order for them to show up in the dialog box:

  1. The name must have an underscore in it.
  2. The data type must be supported (see below for a list of supported data types).
  3. The setting must be UserScoped.

The underscore is required so that it can separate the actual name of your setting from the category you wish to put it in. See the screenshot below for some examples:

You'll notice several settings in the screenshot have double underscores in their names. This was to allow spaces in either the category name or in the setting name itself. You'll also notice that all the names in the screenshot have a number after them. This is for the settings sort index within its own category. The setting needs to have a scope of user, not application. When a setting has a scope of application - it is readonly at runtime, and since we want to change these settings at runtime it must have a scope of user.

There are several data types that are supported by the IDE's Settings Designer, but it is a little more difficult to support data types such as a TimeSpan, or a GUID. While a TextBox could provide support for editing these, I didn't want to mess with the validation, and the use of these as User scoped objects that you'd want to change in an Options dialog, I felt, was rare. The list of supported types:

  • Byte
  • Char
  • Decimal
  • Double
  • Integer
  • Long
  • SByte
  • Short
  • Single
  • String
  • UInteger
  • ULong
  • UShort
  • System-defined Enums (added on 12-12-2005)

Using this form

Using the form is like using any other form. Declare an instance of it and use the ShowDialog method. There are several different styles to choose from - see below for more details on them.

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

The styles (12/12/2005)

There are four different styles that you can use. TreeView and TabPages aren't anything new, but since 12/12/2005 I've included support for FireFox1 and FireFox2. FireFox1 is the style of the options box in FireFox before version 1.5 came out. FireFox2 is the style of FireFox version 1.5. Just changing that one line of code f.Style = frmOptions.OptionsStyle.FireFox2 you can change the look of the dialog box. Watch out when using the TreeView style, as it can be confusing for non-technical users (which most likely make up a majority of your user base - thanks Anna). For the FireFox styles, you can also add images. Currently these images must be 32x32 for the controls width/height support, however feel free to modify the code to support other sizes. Here is an example from the downloadable source:

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 allows you to add the images. Here I have all my images loaded as resources so that I can easily reference them. You must specify the main group that each image ties to as you add them, or they will not show up.

TreeView

TabPages

FireFox1

FireFox2

The form

The form is relatively simple. I have a TreeView anchored on the left with a TableLayoutPanel anchored on the right. These serve as the housing for the settings. One note about the TreeView - the path separator is a period. There is also a checkbox, so that the users can choose whether they want to save their settings when the application exits or not, as well as the standard "OK", "Cancel" and "Apply" dialog buttons.

Loading the settings

In order to be able to change the settings, but not apply them (hence the Apply and OK buttons) we need to have a storage spot for all our setting information. So, I created a class with a collection to store that information for us - SettingInfo and SettingInfoCollection. Each object of SettingInfo needs to store the Name, Category, SortIndex, and Value. There is a subroutine in the class that will load all these, when called passing it the true setting name (what you see in the designer). The collection should return to us all the settings of a given category, and change a value (or even a full item for sorting) for a given Index or true name.

In the Load event of the form, we need to load all the settings available to us. To do that we need to cycle through each SettingsProperty in My.Settings.Properties, adding each one to the collection:

'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()

To load the categories into the TreeView (see the LoadTreeView() method), I have a function that adds the categories/sub-categories from an array.

Displaying the edit controls

After a category is selected from the TreeView - which should happen when you first display the form - the controls need to be displayed. The TreeView was an optimal control for displaying the categories because of the FullPath property of the nodes. So, in order to get all the settings of the selected category we just use the function provided in the class:

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

From here, I cycle through all the settings returned to me, and determine the appropriate control to use for editing, adding handlers to each control's LostFocus event to update the value stored in the collection.

Applying the settings

Applying the settings is very easy - just loop through each setting in the collection and update the value stored in the My.Settings namespace:

'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

Hitting either the OK or Apply button will trigger the code given above. Apply will not close the dialog box. OK sets the DialogResult to OK and is the Accept button of the form. Cancel is the Cancel button of the form and will set DialogResult to CANCEL.

During runtime, if you've unchecked the save settings on the exit checkbox, the settings will apply correctly when you change them, but after you restart the application they will again be at their defaults. Leaving it checked will ensure that the settings you've changed are carried on to the next run of the program.

Conclusion

I really hate writing conclusions. I'll let you, the readers, come to your own conclusion about this code. I hope you find this helpful and easy to use.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here