Skip to main content
Email Password   helpLost your password?

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:

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. Feel free to send any comments/suggestions/bug reports to codeproject@stdominion.net or just leave a message below.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralSuggested Code for Flicker Reduction Pin
Solution_00
14:04 24 Apr '08  
GeneralSuggestions - RFC Pin
Ray Cassick
19:32 28 Dec '06  
GeneralRe: Suggestions - RFC Pin
Chris Kolkman
2:06 29 Dec '06  
GeneralRe: Suggestions - RFC Pin
Anand1107
2:29 22 May '07  
Generalsort accending or descending a line in text.txt Pin
jean.king
7:30 21 Jul '06  
GeneralWhoa! Pin
AndrewVos
21:31 17 Jul '06  
QuestionAdding to my project Pin
FreQi
11:01 5 Mar '06  
AnswerRe: Adding to my project Pin
Chris Kolkman
2:17 6 Mar '06  
GeneralRe: Adding to my project Pin
FreQi
15:14 7 Mar '06  
GeneralRe: Adding to my project Pin
FreQi
16:17 7 Mar '06  
GeneralRe: Adding to my project Pin
Chris Kolkman
16:39 7 Mar '06  
GeneralRe: Adding to my project Pin
FreQi
4:56 8 Mar '06  
GeneralRe: Adding to my project Pin
FreQi
20:23 8 Mar '06  
GeneralRe: Adding to my project Pin
Chris Kolkman
1:58 9 Mar '06  
GeneralRe: Adding to my project Pin
FreQi
6:17 9 Mar '06  
GeneralWhere is FireFox panel? Pin
massimo.magris
22:52 22 Jan '06  
GeneralRe: Where is FireFox panel? Pin
massimo.magris
23:02 22 Jan '06  
GeneralRe: Where is FireFox panel? Pin
Chris Kolkman
2:43 23 Jan '06  
GeneralDialog for c# Pin
Dalli
21:09 15 Dec '05  
GeneralRe: Dialog for c# Pin
Chris Kolkman
2:03 16 Dec '05  
GeneralRe: Dialog for c# Pin
okcode
1:32 18 Jun '06  
Generalsupport for enum Pin
Peter Spiegler
5:36 11 Dec '05  
GeneralRe: support for enum Pin
Chris Kolkman
9:28 12 Dec '05  
QuestionHow to use on another form Pin
ArgoDragon
18:46 24 Nov '05  
AnswerRe: How to use on another form Pin
Chris Kolkman
4:09 25 Nov '05  


Last Updated 14 Dec 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009