Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - SaveSettings.jpg

Introduction

The .NET Compact Framework does not contain an AppSettings class like the full framework. On the full .NET Framework a developer could gain access to settings stored in the App.Config file by creating a name value collection from the System.Configuration.ConfigurationSettings.AppSettings class. As an advocate of uniformity, I wanted to create something that had similar functionality on the Compact Framework. This article will show you what I came up with.

Using the code

My first step was to create an XML file that looked a lot like the App.Config file in .NET.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="ServerIP" value="192.168.5.22" />
        <add key="UserName" value="testuser" />
        <add key="Password" value="jdhs822@@*" />
        <add key="PhoneNumber" value="5555555555" />
        <add key="TimeOut" value="60" />
        <add key="LastTransmit" value="03/03/2004 9:12:33 PM" />
        <add key="DatabasePath" value="\Program Files\DB\test.sdf" />
    </appSettings>
</configuration>

I named this file Settings.xml and added it to my project with a build action of content. This ensures that the file will get downloaded to my program's executing folder.

My next step was to create a new class called Settings. This class contains only static members so the settings are accessed from the file only once during program execution and the entire program will have easy access to these values.

I wanted the settings to be loaded as soon as the settings were accessed, so I created a static constructor and placed my XML parsing code inside the constructor.

m_settings is a NameValueCollection that stores all of the settings.

public class Settings
{
    private static NameValueCollection m_settings;
    private static string m_settingsPath;

    // Static Ctor

    static Settings()
    {
        // Get the path of the settings file.

        m_settingsPath = Path.GetDirectoryName(
        System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        m_settingsPath += @"\Settings.xml";

        if(!File.Exists(m_settingsPath))
            throw new FileNotFoundException(
                              m_settingsPath + " could not be found.");

        System.Xml.XmlDocument xdoc = new XmlDocument();
        xdoc.Load(m_settingsPath);
        XmlElement root = xdoc.DocumentElement;
        System.Xml.XmlNodeList nodeList = root.ChildNodes.Item(0).ChildNodes;

        // Add settings to the NameValueCollection.

        m_settings = new NameValueCollection();
        m_settings.Add("ServerIP", nodeList.Item(0).Attributes["value"].Value);
        m_settings.Add("UserName", nodeList.Item(1).Attributes["value"].Value);
        m_settings.Add("Password", nodeList.Item(2).Attributes["value"].Value);
        m_settings.Add("PhoneNumber",
                                  nodeList.Item(3).Attributes["value"].Value);
        m_settings.Add("TimeOut", nodeList.Item(4).Attributes["value"].Value);
        m_settings.Add("LastTransmit",
                                  nodeList.Item(5).Attributes["value"].Value);
        m_settings.Add("DatabasePath",
                                  nodeList.Item(6).Attributes["value"].Value);
    }
}

Now, we need some public accessors to retrieve the values from the NameValueCollection.

public static string ServerIP
{
    get { return m_settings.Get("ServerIP"); }
    set { m_settings.Set("ServerIP", value); }
}

public static string UserName
{
    get { return m_settings.Get("UserName"); }
    set { m_settings.Set("UserName", value); }
}

// ... And so on

The only thing left to do is to add a method for updating our settings. The XmlTextWriter class provides us with a light-weight mechanisim for writing xml to a FileStream. We iterate through the NameValueCollection and create the settings in xml.

public static void Update()
{
    XmlTextWriter tw = new XmlTextWriter(m_settingsPath,
                                       System.Text.UTF8Encoding.UTF8);
    tw.WriteStartDocument();
    tw.WriteStartElement("configuration");
    tw.WriteStartElement("appSettings");

    for(int i=0; i<m_settings.Count; ++i)
    {
        tw.WriteStartElement("add");
        tw.WriteStartAttribute("key", string.Empty);
        tw.WriteRaw(m_settings.GetKey(i));
        tw.WriteEndAttribute();

        tw.WriteStartAttribute("value", string.Empty);
        tw.WriteRaw(m_settings.Get(i));
        tw.WriteEndAttribute();
        tw.WriteEndElement();
    }

    tw.WriteEndElement();
    tw.WriteEndElement();

    tw.Close();
}

Now we can easily access our settings from anywhere in our application!

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralDid exactly what it should
Bernhard
23:46 11 Mar '10  
thank you.

All the label says is that this stuff contains chemicals "... known to the State of California to cause cancer in rats and low-income test subjects."
Roger Wright
http://www.codeproject.com/lounge.asp?select=965687&exp=5&fr=1#xx965687xx


GeneralMy vote of 1
Nedyalko Zhekov
12:22 19 Jan '10  
poor
QuestionLittle problem
7:29 16 Mar '07  
Hi, nice work with this article, i only have a problem, that when i start the application it saves the data, (seems that in a temp file), couse when i closed and started again the values are no update.
i want to know what im doing wrong or does someone has similar problem and how can i fixit
thanks
GeneralAccess Violation Error
r20j
1:18 30 Nov '05  
I Succesfully ported the Application to VB.Net On two instances.
In one it runs fine.
In second it gives an Error.
Unauthorised access violation.
Any Suggestion welcome
Rajesh.
GeneralVery Useful
Paul Baker
11:54 18 Aug '05  
Really good, easy to follow, simple demo. I wanted to write a small pocket pc application to keep count on a number of different items where the user can add or delete new counters and increase any counter by one or reset the counter.

This demo provided the backbone code I needed for saving my counter values...with a small bit of tweaking it did exactly what I wanted and I'm sure saved me a good couple of hours rooting around looking at the documentation for xml manipulation in the compact framework.

Great job...thanks a lot.
GeneralXML File is not being copied over
jfaubey2000@yahoo.com
9:42 21 Jul '05  
I added a new File to the project AppConfig.XML. When I deploy to the Emulator, the file is not being copied along with the EXE. What am I missing.

Thanks

GeneralRe: XML File is not being copied over
zero_joker
7:27 20 Nov '06  
Same problem here. What settings do I have to do to make sure the .xml file is copied over to the device to the appropirate location?

thanks!
GeneralRe: XML File is not being copied over
Agha.net
12:44 20 Sep '07  
Ok select your xml (AppConfig.XML) file in visual studio right click -> Properties -> set Copy to output director = "copy always"

cheers

Agha Usman
Generaltiny improvement
flair
22:33 6 Apr '05  
for (int i=0; im_settings.Add(nodeList.Item(i).Attributes["key"].Value, nodeList.Item(i).Attributes["value"].Value);
}

instead of:
m_settings.Add("ServerIP", nodeList.Item(0).Attributes["value"].Value);
m_settings.Add("UserName", nodeList.Item(1).Attributes["value"].Value);
m_settings.Add("Password", nodeList.Item(2).Attributes["value"].Value);
...
GeneralRe: tiny improvement
flair
22:34 6 Apr '05  
sorry, should be this:
for (int i=0; i m_settings.Add(nodeList.Item(i).Attributes["key"].Value, nodeList.Item(i).Attributes["value"].Value);
}
GeneralRe: tiny improvement
flair
22:36 6 Apr '05  
Why the code cannot be shown corretly?..
for (int i=0; i<nodeList.Count; ++i)
m_settings.Add(nodeList.Item(i).Attributes["key"].Value, nodeList.Item(i).Attributes["value"].Value);
GeneralSystem.NullReferenceException
wannafly
8:36 12 Apr '04  
I (tried) to port this to VB, but i seem to get a System.NullReferenceException whenever I call any of the properties, it seems as if the m_settings object is not persisting? It reads the data in fine but once i leave New() m_settings gets set to nothing, any ideas?
GeneralAny chance you could port it to VB
Geovani
6:56 5 Apr '04  
First off I would like to thank you for what I think is a great example of savings settings; second I would like to ask if it's not too much of a hastle to provide the code in CF VB.NET format, I just started programing and C# is my next language; Like I said if it's not too much of a hasle.
GeneralA misprint
Alexey Mochalov
21:47 21 Mar '04  
The following snippet of code:
tw.WriteStartAttribute("value", string.Empty);
tw.WriteRaw(m_settings.Get(0));
should be as follows:
tw.WriteStartAttribute("value", string.Empty);
tw.WriteRaw(m_settings.Get(i));

GeneralRe: A misprint
pbrooks
5:07 22 Mar '04  
I fixed it. Thanks! Big Grin

Thanks,
Page Brooks
www.explosivedog.com


Last Updated 24 Mar 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010