Archive

Posts Tagged ‘serialization’

It’s Optional

April 19th, 2009
Comments Off

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:

Settings dialog

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.

david Programming , , ,