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 DataSet
s, 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.
="1.0" ="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
DataTable
s can contain multiple rows, and a DataSet
can even contain multiple related or unrelated DataTable
s.
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 DataSet
s, you can easily store your settings
in XML files.