Skip to main content
Email Password   helpLost your password?

Introduction

INI files and the registry are generally things of the past for .NET applications. But what to use? XML seems appropriate, but one look at System.XML is enough to scare most developers off, especially just to store a few fields. Fortunately, there is a very easy way in .NET to solve this, but one that is usually not seen by developers. In this article, I�ll explain how you can easily store and retrieve your application settings with just a few lines of code.

History

In Windows 3.1, developers used INI files to store settings. In general, they worked pretty well for simple settings, but were not appropriate for more complex data. INI files also did not account for multiple users, and thus Microsoft invented the registry.

Along came the registry with Win32. The registry was fast, hierarchical, multi user, and allowed storage of typed data. But unfortunately, the registry was a central system component and was not contained as part of the application install.

Next, XML became popular. XML offers fast, hierarchical storage of typed data. However, XML is so flexible that for most users doing anything simple is quite an undertaking. Fortunately, there are easier ways than using System.XML and handling everything yourself.

Old Ways

Many users have simply resorted to using INI files or the registry. INI files are not supported in .NET. To use INI files, a developer must call the Win32 API directly, or use some prepared classes on the Internet that use the Win32 API. For the registry, classes are available in Microsoft.Win32. XML however is portable and can be easily edited by end users if necessary.

How

The secret to painless XML settings files is to use a typed DataSet. A typed DataSet is actually an in memory dataset for working with ADO.NET, but they have many other uses as well. To add a typed DataSet to your application, right click on the project in the Solution Explorer, and select Add New Item. Now select DataSet, and give the dataset a name.

Now, we have a blank DataSet in our project. For the purposes of a demo, I have created a main form already that looks like this.

I have chosen these for the demo as they give us three types of data to store, a string, an integer, and a Boolean. Now, let�s design our DataSet around these.

Open the Solution Explorer and find the newly created DataSet.

When you double click on Settings.xsd, you will see a designer like this:

This is a blank DataSet. A DataSet can contain several tables, but for this demo, we will add just one. Open the toolbox, and you will see different items than you normally see in a WinForms or a WebForms application.

There are a lot of items in the toolbox related to DataSets, but for the needs of this article, we only need Element. Double click on Element to add one to the DataSet. The DataSet should now look like this:

The Element type corresponds to a DataTable. Let�s name it Main (change the highlighted text above to Main). Now, let�s enter the fields that we want to store. The element should look like this when finished:

Visual Studio will now take this DataSet and make a set of classes for us that we can use. So now, let�s take a look at the Load and Save buttons on the main form. These events make use of ConfigPathname, this is a field that is predefined in the demo. ConfigPathname just holds the path and filename of the settings file.

C#

private void butnSave_Click(object sender, System.EventArgs e) {
    Settings xDS = new Settings();
    Settings.MainRow xRow = xDS.Main.NewMainRow();
    xRow.Username = textUsername.Text.Trim();
    xRow.PIN = int.Parse(textPIN.Text.Trim());
    xRow.Admin = chckAdmin.Checked;
    xDS.Main.AddMainRow(xRow);
    xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema);
}

private void butnLoad_Click(object sender, System.EventArgs e) {
    if (new FileInfo(ConfigPathname).Exists) {
        Settings xDS = new Settings();
        xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema);
        if (xDS.Main.Rows.Count > 0) {
            Settings.MainRow xRow = xDS.Main[0];
            if (!xRow.IsUsernameNull()) {
                textUsername.Text = xRow.Username;
            }
            if (!xRow.IsPINNull()) {
                textPIN.Text = xRow.PIN.ToString();
            }
            if (!xRow.IsAdminNull()) {
                chckAdmin.Checked = xRow.Admin;
            }
        }
    }
}

Visual Basic.NET

Private Sub butnSave_Click(ByVal sender As System.Object, 
ByVal e As System.EventArgs) Handles butnSave.Click
  Dim xDS As New Settings
  Dim xRow As Settings.MainRow
  xRow = xDS.Main.NewMainRow
  xRow.Username = textUsername.Text.Trim()
  xRow.PIN = Int32.Parse(textPIN.Text.Trim())
  xRow.Admin = chckAdmin.Checked
  xDS.Main.AddMainRow(xRow)
  xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema)
End Sub

Private Sub butnLoad_Click(ByVal sender As System.Object, 
ByVal e As System.EventArgs) Handles butnLoad.Click
  If New FileInfo(ConfigPathname).Exists Then
    Dim xDS As New Settings
    Dim xRow As Settings.MainRow
    xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema)
    If xDS.Main.Rows.Count > 0 Then
      xRow = xDS.Main.Rows.Item(0)
      If Not xRow.IsUsernameNull() Then
        textUsername.Text = xRow.Username
      End If
      If Not xRow.IsPINNull() Then
        textPIN.Text = xRow.PIN.ToString()
      End If
      If Not xRow.IsAdminNull() Then
        chckAdmin.Checked = xRow.Admin
      End If
    End If
  End If
End Sub

When loading the DataSet back, it is necessary to check each field for null. In our demo, they would never be null, but if you later add fields and your application tries to load a file that was saved with an older version, fields could be null. End users might also directly edit your settings files. Accessing a field while it is null will generate an exception.

If you run the demo, you can enter some test values and then click Save.

After clicking Save, the demo will create a .settings file in the same directory as the .exe. Normally, this is bin/debug/SettingsDemo.exe.Settings. If you open this file, you will see it is a standard XML file and can easily be edited.

<?xml version="1.0" standalone="yes"?>
<Settings xmlns="http://tempuri.org/Settings.xsd">
  <Main>
    <Username>Kudzu</Username>
    <PIN>1234</PIN>
    <Admin>true</Admin>
  </Main>
</Settings>

Now, if you run the application again, you can click the Load button to load these settings.

In this demo, we only stored one row in the DataTable. But DataTables can contain multiple rows, and a DataSet can even contain multiple related or unrelated DataTables.

Conclusion

XML files are a widespread standard that allows easy storage of structured typed data. Use of XML files allows easy editing by end users, and even by other software. Using typed DataSets, you can easily store your settings in XML files.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralDataSet.ReadXml has arror
Makso
23:18 13 Aug '09  
Good day!

Can You help me please?

I have this problem:

When I use DataSet.ReadXml method for read xml file




SHYMKENT_SF
Тип



then message is appears - An anhandled exception of type 'System.Xml.XmlException' occured in system.xml.dll (Additional information: System error)

I think its error appears because I use russion text in file - Тип. How to solve this problem?

TIA, Max.
Sign In·View Thread·PermaLink
GeneralRe: DataSet.ReadXml has arror
Chad Z. Hower aka Kudzu
4:46 14 Aug '09  
I cant see your error, so I cant help much. Russian text should be no problem. If you want to send me a standalone ready to run project I can take a look at it.

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink2.00/5
GeneralRe: DataSet.ReadXml has arror
Makso
0:56 18 Aug '09  
Forgive me for a question. I have understood in what a problem.

If to create an xml-file through a windows notepad, and to add in it the Russian text at its opening the Internet Explorer will be an error.

If the xml-file has been created during save DataSet, there is the same.

I have created an xml-file in Visual Studio and at me all has earned.

HAGO, Makso.
Sign In·View Thread·PermaLink
GeneralRe: DataSet.ReadXml has arror
Chad Z. Hower aka Kudzu
16:37 18 Aug '09  
Try running the program and having it create the XML file. Also check the encoding options, I don't remember what I used or if I specified a hard coded one.

If you use Notepad or other, you will need to make sure it saves as Unicode and also the VS reads it in as Unicode rather than ANSI.

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
Generalgood article
Donsw
17:24 8 May '09  
Nice work

cheers,
Donsw
My Recent Article : Ajax Calendar Control

Sign In·View Thread·PermaLink
GeneralTrue but....
AhsanS
18:33 9 Nov '08  
Hi Chad,

Your solution is fine and will work well. You have explained it well enough too, but datasets are not meant for this purpose. Simply using XPath and providing expressions to get values is the right way of doing it for me.

Ahsan Ullah
Senior Software Engineer
MCTS 2.0

Sign In·View Thread·PermaLink
GeneralRe: True but....
Chad Z. Hower aka Kudzu
16:15 18 Nov '08  
Of course Datasets were not designed for this. They just work very well, and epescially when I wrote this .NET 1.1 was the only version out. Since then there are many more options. There is nothing wrong with raw XML, but its more work for most especially those no familiar with the deeper details of XML.

But even in the world of .NET 3.5 I find myself often using datasets because they are very easy to use.

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink1.00/5
GeneralHow to secure these settings?
vinay_kawade
14:12 14 Jul '08  
Hi Chad,

Some one can easily change the content of the XML file.

In the above example, one can simply go to the config file path and change the user PIN?

how do you prohibit that.

Where do I keep the data that needs to be secured?

VInK
Sign In·View Thread·PermaLink
GeneralRe: How to secure these settings?
Chad Z. Hower aka Kudzu
14:31 14 Jul '08  
That is actually a feature most people want. The ability for users to edit.

If you want to hide something, you need to encrypt it. The level of encryption depends on the data. You can also encxrypt just individual keys, instead of the whole file.

There are encryption functions built into .NET, or for passwords and things you can use easier more standard practices of storing hashes. Which hash/encryption again depends on your required security level.

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
GeneralAdd a field later?
StephenKearney
11:11 15 Sep '07  
Great article. Thanks to it I'm successfully using XML files for application settings and data. However I realize that I may run into a problem in the future. Because my application is constantly being improved I add new features to it now and then. If I need to store any new data I'll have to revise my dataset by adding fields. If I then try to load an old XML file (from before the fields were added) it will throw an exception due to the fields mismatch.

Is there any elegant way to get around this limitation? I could write some functions to identify the version of the dataset in the XML file and then convert old to new versions but that seems a bit clunky. There must be a better way (at least I'm hoping there is).
Sign In·View Thread·PermaLink
GeneralRe: Add a field later?
Chad Z. Hower aka Kudzu
8:36 8 Oct '07  
This should only happen if you change data types or add new fields that are required.

If you need to do that, you can version your files by embedding version information.

However since .NET 2.0 there are built in settings classes that replace much (not all, some cases my method is better) of this funciontality. You should check them out too.

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
Generali know you from somewhere...
ferdna
10:56 8 Sep '07  
chad... i think i remember you!!!!!!! wheren't you a hardcore Borland Delphi developer...???
nice seen you in the .net world...

It Is Not That I'm Different!
... I'm Only Making The Difference!

Sign In·View Thread·PermaLink
GeneralRe: i know you from somewhere...
Chad Z. Hower aka Kudzu
1:16 2 Feb '08  
Yes thats me. Smile

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
GeneralMultiple Dtata tables
sid_boss
3:10 16 Mar '07  
This is a great article...I was just wondering what would be the best way to handle multiple data tables writing to the same file...coz it seems that the current method suggested will create a new settings file everytime and hence remove the sections corresponding to other tables..do i need to fill the DS everytime i plan to update a table?

please excuse if the query is silly, but am new to all this...
Sign In·View Thread·PermaLink2.00/5
GeneralRe: Multiple Dtata tables
Chad Z. Hower aka Kudzu
1:17 2 Feb '08  
Yes you would need to read first then modify before saving. In fact the samples do that..

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
GeneralDarn It
SteveWaNet
18:42 24 Nov '06  
This looks like such the perfect solution for my winforms app I'm writing. But then I open up my Solution in C# Express Edition, add a DataSet, and... it's the end of my game:

Express Edition has only a mere fraction of the "tools" in the toolbox for Dataset.

No Element.

Only TableAdapter, Query, Datatable, and Relation.

I think I'll just read up on how to serialize on object to xml and do it the manual way.

Thanks for the code, though. I'll probably ending using in the futre.
Steve

"Just trust yourself, then you will know how to live." - Goethe

Sign In·View Thread·PermaLink
GeneralRe: Darn It
SteveWaNet
8:27 25 Nov '06  
For those with Express Edition, I found the following

http://www.builderau.com.au/program/dotnet/soa/Use_XML_to_store_configuration_settings/0,339028399,339211304,00.htm

But, anyhow, thanks again Chad.

"Just trust yourself, then you will know how to live." - Goethe

Sign In·View Thread·PermaLink
GeneralRe: Darn It (No Element is VS 2008 Team Suite) [modified]
Michael9000
17:10 3 Dec '09  
Well I have the same problem - no Element in the ToolBox - and that is with VS2008 Team Suite!
Am I missing a reference or something else?

Edit:
No missing reference. It's the same in the demo.
Do I need to add something to the ToolBox to add a Element to the DataSet?


You got my 5, though it's an rather old article, it has some good points Smile

modified on Thursday, December 3, 2009 10:20 PM

Sign In·View Thread·PermaLink
GeneralButton backcolor
The Mighty Atom
8:48 1 Sep '06  
Great article!

I was wondering, how can you save/load backcolors of controls? I have a couple of buttons in my app to show a color to the user. This is done with a colordialog control.

I've added this to the butnSave_Click event:

xRow.Color = view32Dialog.Color.R & ChrW(32) & view32Dialog.Color.G & ChrW(32) & view32Dialog.Color.B

When you click a button, a colordialog appears where the user selects a color. After that, a flat button you cannot click, shows that color. When i click the Save button, the rgb values of that color are written as:

xxx xxx xxx
(xxx xxx xxx = R G B)

in the settings file. So far so good.

But i can't seem to load the color so that it is applied on the button. I tried this:

If Not xRow.IsColorRNull() Then
view32Dialog.Color = xRow.Color
End If

This doesn't work. The words xRow.Color are blue underlined, and i get the message "Error: Value of type 'String' cannot be converted to 'System.Drawing.Color". So im kinda stuck here.

Can you help me?

I also succesfully added a combobox control and this works fine, since this is pretty much like a textbox. Smile
Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
Chad Z. Hower aka Kudzu
3:38 2 Sep '06  
When you are saving Color you are converting it to a string. If you want to store it that way, when you read it back you need to convert it to the type that color is. I'm not at my dev PC now, but IIRC Color might be a descendant of int.


Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
The Mighty Atom
4:44 2 Sep '06  
Thanks.

But im affraid i need some more help with that. See, im just a student, and pretty new to .NET

You say that i need to convert it to the type that color is. I tried Integer and string, and none of them work. It saved the color rgb's as string, but i cannot convert the string back to color. Or something like that.

Could you help me out? Thanks. Smile
Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
Chad Z. Hower aka Kudzu
5:02 2 Sep '06  
Im not able to look right now as Im preparing to fly out. Check the type of color and see if it descends from Int. If not, look at parsing routines to convert string back to it.


Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"

My Technical Stuff:
http://www.KudzuWorld.com

My Blogs:
http://www.KudzuWorld.com/blogs/

Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
The Mighty Atom
6:49 2 Sep '06  
Im don't really know what you meen by that, but ill try.
I tried many things like:

- With and without the Trim thingy.
- With and without the ToString thingy.
- With and without the view32dialog.
- With and without the Parse thingy.
- Tried System.Int32 and System.String in the Settings.xsd file.
- xRow.Color = view32Dialog.Color.R & ChrW(32) & view32Dialog.Color.G & ChrW(32) & view32Dialog.Color.B
- xRow.Color = view32Dialog.Color.ARGB
- And many more things and variations, i just can't get it to work.

I keep on getting errors. My geuss it that it doesn't know what to do with the RGB string, since it is not a color value yet.

This is a pain in the butt, because my app will be completed when i have this working.

A color value from a ColorDialog, is that a String, Integer or even an Object type?

Geuss ill have to wait untill you're back, you're my only hope! Smile
Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
The Mighty Atom
4:35 11 Nov '06  
My app is still not finished because im still stuck with this.
I really need help with this, i tried everything and could'nt get it to work.Frown
Sign In·View Thread·PermaLink
GeneralRe: Button backcolor
Michael9000
17:37 3 Dec '09  
save r, g and b to settings
Button btn  = new Button();
int r = btn.BackColor.R;
int g = btn.BackColor.G;
int b = btn.BackColor.B;


load r, g and b from settings
 
Color c = Color.FromArgb(int red, int green, int blue);
btn.BackColor = c;

Sign In·View Thread·PermaLink


Last Updated 27 Oct 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009