It’s Optional
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.
