![]() |
Languages »
XML »
XML/XSLT
Intermediate
Quick and Dirty Settings Persistence with XMLBy circumpunctA quick and dirty use of an XML file to save program settings between application execution sessions. |
XML, C# 2.0.NET 2.0, Win2K, WinXPVS2005, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
The demo project is just a form that remembers its Top and Left values. I'm sure you've seen a gray form with no controls before, so I've spared you the graphic.
Yes, I'm afraid it's yet another class to save application settings in an XML file. Why, when there are so many similar articles here? Well, most of them use classes that are big, and some are huge! Great when you need them, but do we really need to use a DLL built from tens of files and thousands of lines of code just to save a few simple settings? In many cases, no.
I shall not get into this as it's well covered elsewhere - but basically, you should be saving your settings in XML these days. (Ideally, this will let you move an entire .NET application, including its settings, to another PC just by copying the application folder.)
This class is quick and dirty. It has no customised trapping of unexpected errors, is not optimized to the last decimal point, and will probably offend the 'best practice' gurus. But it's small, simple, easy to use, and it works.
This is the entire code:
using System;
using System.Windows.Forms;
using System.Xml;
namespace QuickNDirtyXML
{
public class Settings
{
XmlDocument xmlDocument = new XmlDocument();
string documentPath = Application.StartupPath + "//settings.xml";
public Settings()
{ try {xmlDocument.Load(documentPath);}
catch {xmlDocument.LoadXml("<settings></settings>");}
}
public int GetSetting(string xPath, int defaultValue)
{ return Convert.ToInt16(GetSetting(xPath, Convert.ToString(defaultValue))); }
public void PutSetting(string xPath, int value)
{ PutSetting(xPath, Convert.ToString(value)); }
public string GetSetting(string xPath, string defaultValue)
{ XmlNode xmlNode = xmlDocument.SelectSingleNode("settings/" + xPath );
if (xmlNode != null) {return xmlNode.InnerText;}
else { return defaultValue;}
}
public void PutSetting(string xPath, string value)
{ XmlNode xmlNode = xmlDocument.SelectSingleNode("settings/" + xPath);
if (xmlNode == null) { xmlNode = createMissingNode("settings/" + xPath); }
xmlNode.InnerText = value;
xmlDocument.Save(documentPath);
}
private XmlNode createMissingNode(string xPath)
{ string[] xPathSections = xPath.Split('/');
string currentXPath = "";
XmlNode testNode = null;
XmlNode currentNode = xmlDocument.SelectSingleNode("settings");
foreach (string xPathSection in xPathSections)
{ currentXPath += xPathSection;
testNode = xmlDocument.SelectSingleNode(currentXPath);
if (testNode == null)
{
currentNode.InnerXml += "<" +
xPathSection + "></" +
xPathSection + ">";
}
currentNode = xmlDocument.SelectSingleNode(currentXPath);
currentXPath += "/";
}
return currentNode;
}
}
}
To use it, just drop the settings.cs file into your project (changing the namespace, if you like). Provide a path to the setting and a default value:
private void Form1_Load(object sender, EventArgs e)
{
this.Top = settings.GetSetting("Form1/Top", this.Top);
this.Left = settings.GetSetting("Form1/Left", this.Left);
}
private void Form1_FormClosing(object sender,
FormClosingEventArgs e)
{
settings.PutSetting("Form1/Top", this.Top);
settings.PutSetting("Form1/Left", this.Left);
}
This generates an XML file like this:
<settings>
<Form1>
<Top>187</Top>
<Left>256</Left>
</Form1>
</settings>
Why pass a path rather than a pair of strings? Well, you can go down as many nodes as you like (within reason) and are not limited to just a group and a key, so you can do handy things like this:
<settings>
<Items>
<Forms>
<Form1>
<Top>187</Top>
<Left>256</Left>
<Buttons>
<Button1>
<Top>10</Top>
<Left>40</Left>
</Button1>
<Button2>
<Top>10</Top>
<Left>80</Left>
</Button2>
</Buttons>
</Form1>
<Form2>
<Top>187</Top>
<Left>256</Left>
</Form2>
</Forms>
</Items>
</settings>
The Type of the default value determines which overload is called and consequently the Type of the returned value. The class handles strings natively, and there is an overload for integers:
public int GetSetting(string xPath, int defaultValue)
{
return Convert.ToInt16(GetSetting(xPath,
Convert.ToString(defaultValue)));
}public void PutSetting(string xPath, int value)
{
PutSetting(xPath, Convert.ToString(value));
}
You can add other overloads if you need them, following the same structure. (Don't forget to specify the culture for converting dates etc., or you can get inconsistent results if the user changes the ambient culture between reading and writing.)
Let the flaming begin :)
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 9 Sep 2006 Editor: Smitha Vijayan |
Copyright 2006 by circumpunct Everything else Copyright © CodeProject, 1999-2009 Web10 | Advertise on the Code Project |