Exploring the Sample GUI Application
Figure 5 shows the simple GUI for the sample application described in this article to illustrate using various settings.
 | |
| Figure 5. Sample GUI: Here's a design-time view of the sample application. |
The application will fill in the "TBD" text shown in labels and text box fields at runtime. The DataGridView, shown with a single column in
Figure 5, provides a visual outlet for the
ItemList ArrayList created earlier. The Save button is there as a convenience; you could use it to update persistent settings without quitting the program (it will call exactly the same method that is called when actually quitting).
Typically, you want to access settings from Windows Forms during specific events, such as startup, shutdown, or to respond to specific user events. The code below shows all three types:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SaveToFile();
}
private void saveButton_Click(object sender, EventArgs e)
{
SaveToFile();
}
private void Form1_Load(object sender, EventArgs e)
{
LoadDataGridView(myDataGridView);
preferredPathTextBox.Text = Properties.Settings.Default.PreferredPath;
lastRunTimeLabel.Text =
Properties.Settings.Default.LastRunTime.ToString();
domainLabel.Text = Properties.Settings.Default.PlanetarySystem;
}
private void SaveToFile()
{
Properties.Settings.Default.ItemList = DGVtoList();
Properties.Settings.Default.PreferredPath = preferredPathTextBox.Text;
Properties.Settings.Default.LastRunTime = DateTime.Now;
Properties.Settings.Default.Save();
}
}
| Author's Note: I have omitted the DGVtoList and LoadDataGridView methods referenced in the preceding code, as they are not germane to the main focus, but they are available in the sample project code. |
As noted earlier, terminating the program (form closing event) and clicking the Save button (button click event) both call the
SaveToFile method.
When the form loads, it populates the TextBox, the two Labels, and the DataGridView from the values available in the application settings. These are automatically loaded by the .NET framework from the application configuration file. You access them via the
Properties.Settings.Default.<name> notation that you see in the code. Note that the settings are strongly typed. Thus, to set the
Text property of the Label to the DateTime object stored in the
LastRunTime setting, you must invoke its
ToString method.
If you compile your project as an executable (.exe), its configuration filestored in the same directorywill be called
app.exe.config, where "app" is the name of your executable file. Recall that settings may be application-scoped or user-scoped. All application-scoped settings reside in the
app.exe.config file. User-scoped settings are also in the
app.exe.config file initially; the .NET framework loads them from
app.exe.config the very first time you execute the programand continues to load them from that file as long as you do not save any changed user-scoped settings.
Looking now at the
SaveToFile method, note that it simply makes assignments into
Properties.Settings.Default.<name>. However, it stores only the user-scoped
ItemList,
PreferredPath, and
LastRunTime settings, not the
PlanetarySystem setting, because that's application-scoped and immutable. The last line of the method invokes the
Settings.Save method, causing the framework to:
- Determine if any settings have indeed been changed.
- Check if the user-scoped settings file exists and if not create it.
- Write the current values of the user-scoped settings to the user's settings file (user.config).
Executing the Sample Application
With the settings code in place,
Figure 6 shows the application when it first launches.
 | |
| Figure 6. First Launch: When you launch the application for the first time, you can see the default values appear in the Domain and Preferred Path fields, but the Last Run Time value is obviously incorrect, and the DataGridView is empty. |
|
 | |
| Figure 7. Second Launch: After closing the application, the Last Run Time value was saved and now displays properly upon a subsequent launch. |
|
|
Remember that the application settings contain initial values for the
PlanetarySystem and
PreferredPath strings but not for the DateTime or the ArrayList settings. So, at first launch, the Last Run Time then shows the textual representation of no value and, as the ArrayList is empty, so is the DataGridView. Now terminate the program and then restart it, and it will look like
Figure 7.
Closing the form runs the SaveToFile() method, which records the date and time when you terminated the program, creating a
user.config file containing the new value for the user-scoped setting. Restarting the program recalls that persistent value and will never again show the default (null) unless and until you delete or rename the user-scoped settings file. This file, by the way, is always called just
user.config. Unlike the application-scoped setting file
app.exe.config, which is stored in the same folder as the executable, the location of
user.config is much more convoluted. A typical path will be something like:
\Documents and Settings\your-user-name\Local Settings\
Application Data\your-company-name\app_xxx_yyy\1.0.0.0\user.config
More generally the path format is:
<Profile Directory>\<Company Name>\<App Name>_<Evidence Type>_<Evidence Hash>\<Version>\user.config
See the description of the components of this path at the
Client Settings FAQ.
Here's the user.config file created when the program terminated for the first time:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<AppSettings.Properties.Settings>
<setting name="PreferredPath" serializeAs="String">
<value>C:\</value>
</setting>
<setting name="LastRunTime" serializeAs="String">
<value>02/27/2007 15:32:02</value>
</setting>
<setting name="ItemList" serializeAs="Xml">
<value>
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</value>
</setting>
</AppSettings.Properties.Settings>
</userSettings>
</configuration>
 | |
| Figure 8: Modifying Values: The Preferred Path value has been modified, and several items were added to the DataGridView. |
Note that the framework writes
all the settings even though only one actually changed. The
PreferredPath in this file still has the same value as the
PreferredPath setting in the
app.exe.config file, and the
ItemList is still empty.
So, with the application still running, go ahead and enter a few values in the ItemList and change the path, as shown in
Figure 8.
Press Save and then look at
user.config again, which now looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<AppSettings.Properties.Settings>
<setting name="PreferredPath" serializeAs="String">
<value>C:\etc\data</value>
</setting>
<setting name="LastRunTime" serializeAs="String">
<value>02/27/2007 15:45:56</value>
</setting>
<setting name="ItemList" serializeAs="Xml">
<value>
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<anyType xsi:type="xsd:string">line one</anyType>
<anyType xsi:type="xsd:string">123456</anyType>
<anyType xsi:type="xsd:string">four score and 7yrs</anyType>
</ArrayOfAnyType>
</value>
</setting>
</AppSettings.Properties.Settings>
</userSettings>
</configuration>
That concludes the discussion of the basics of persistent settings. But it's possible to reduce the amount of code you have to write even further by binding application settings to form controls, giving you the automatic, two-way updates described at the start of this article.