What’s the best way to store and retrieve optional settings or preferences for users for your C# application? For simple stuff, there’s no easier way than creating settings in Visual Studio:

Note that you can use settings for both simple values like bool and string, and for more complex values like colors.
These settings get persisted in a file called [your program name].exe.config.
And you can refer to them in code like this:
private void GetBackgroundColor()
{
this.BackColor = Properties.Settings.Default.BackgroundColor;
}
private void SetBackgroundColor(Color backcolor)
{
Properties.Settings.Default.BackgroundColor = backcolor;
Properties.Settings.Default.Save();
} |
Well, that’s all very well, simple, and very useful. But it gets messy if you want to set up a lot of options and particularly if you need options using your own enums, in various categories or for different states or objects in your application – the Settings dialog is just a very simple, line by line set of options with no structure.
My own preference* is to create one or more Options classes, and to use the nifty Xml Serialization stuff which I talked about previously on this blog to load and save the class.
Here’s a considerably cut-down version of my Options class from my software Chapter Master:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| public class Options
{
public enum ImageGrabOptions
{
None,
CropFromTop,
CropFromLeft,
CropFromRight,
CropFromBottom,
CropFromCentre,
Pad
}
public enum SaveOptions
{
None,
RenameOriginal,
PromptForNew
}
[System.Xml.Serialization.XmlElement()]
public ImageGrabOptions ImageGrab = ImageGrabOptions.CropFromTop;
[System.Xml.Serialization.XmlElement()]
public SaveOptions SaveOption = SaveOptions.PromptForNew;
[System.Xml.Serialization.XmlElement()]
public int PadColorAsInt = Color.White.ToArgb();
[System.Xml.Serialization.XmlIgnore]
public Color PadColor
{
get {
return Color.FromArgb(PadColorAsInt);
}
set {
PadColorAsInt = value.ToArgb();
}
}
public Options()
{
}
public bool Save(string filename)
{
return Seralize.ToXmlFile(filename, this);
}
public static Options Load(string filename)
{
return opts = (Options) Seralize.FromXmlFile(filename, typeof(Options));
}
} |
Where Serialize is a class containing just the Xml serialization routines I wrote based on this Code Project article.
Note the way that the Color is serialized in lines 27-40, the same sort of workaround as is needed for TimeSpan values.
I like this approach because among other things, it allows different sets of preferences to saved and loaded as required.
Accessing these option values is very simple (this code is a fudge written just to demonstrate my general approach):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| private readonly string MySettingsFolder =
System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+ @"\ProgramName";
private OptionClass MyOptions;
private void GetOptions()
{
MyOptions = Options.Load(MySettingsFolder + @"\Default Options.xml");
}
//....and thus code like:
picCover.BackColor = MyOptions.PadColor;
if (MyOptions.ImageGrab.CropFromBottom)
{
//........
}
private bool SaveSpecialOptions()
{
return MyOptions.Save(MySettingsFolder + @"\Special Options.xml");
} |
* I’m happy to have others tell me why there are better ways. As always, I certainly don’t claim to be any kind of expert. This is just the way I like to do it. If you think it’s dumb, tell me so.