RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Exploring Secrets of Persistent Application Settings : Page 3

The .NET framework makes it easier than ever to create application settings and bind them to controls, but you need to know a few secrets to go beyond basic string settings and avoid problems.

Binding Properties to Settings
Binding properties to settings is a simple, two-step process from the current code.

Step One: Create the Bindings
Returning to the visual designer, select the TextBox next to the Preferred Path label, then select Data >> PropertyBinding in the Properties pane, and finally click on the ellipsis. Figure 9 shows the three-step sequence.

Figure 9. Binding Controls to Settings: To bind a control to a setting, select the control, and then click the ellipsis next to the (PropertyBinding) item under the ApplicationSettings item in the Properties pane.
Figure 10: Binding Application Settings: This dialog lets you bind form controls to application settings.
Clicking the ellipsis opens a dialog for binding properties to application settings as shown in Figure 10.

Figure 11: Design-time Binding Results: After binding the Text property to the PreferredPath setting, the correct value appears in the Preferred Path TextBox—even at design-time.
Open the drop-down arrow next to the Text property and select the PreferredPath setting as shown in Figure 10, and then close the dialog. You should see two changes, as shown in Figure 11.

  1. The text in the TextBox will change from "TBD" (which was entered manually when creating the form) to the PreferredPath application setting value.
  2. The Text property binding appears in the Properties pane.
Do the same thing for the Domain field, binding it to the PlanetarySystem setting. But unfortunately, that's as much as you can accomplish in the visual designer. As Figure 12 shows, only those two settings are available in the binding drop-down.

What happened to the other two settings? The answer is that they're not available because they're not simple strings—and a form can display only strings when it comes right down to it. That is why, if you look back at the code, that we had to convert the setting to a string:

   lastRunTimeLabel.Text = 
Figure 12. Available Settings: Only two of the four possible settings are available for binding at design-time.
Automatic design-time binding, then, is not available for all settings, but because so many properties are just strings, design-time binding works fine most of the time.

Step Two: Remove Unneeded Code
Because two of the settings are now automatically bound, you can remove the code that manually bound those settings before. The following code has commented-out references to the PreferredPath and PlanetarySystem (two lines in the Form1_Load method and one line in SaveToFile):

   private void Form1_Load(object sender, EventArgs e)
      // preferredPathTextBox.Text = 
      lastRunTimeLabel.Text = 
      // domainLabel.Text = 
   private void SaveToFile()
      Properties.Settings.Default.ItemList = DGVtoList();
      // Properties.Settings.Default.PreferredPath = preferredPathTextBox.Text;
      Properties.Settings.Default.LastRunTime = DateTime.Now;
As you can see, if this application had only string settings, you could eliminate all settings-related code in the Form1_Load method and you would need only one line of code in Form1_Closing (or in this case the SaveToFile method):

Author's Note: If one line of code is still too much, then I'm afraid you will have to switch to Visual Basic for the final leap to zero lines of code, as C# doesn't support this. Yes, with Visual Basic, you do not even need the Save method call (see point #7 in How to: Create Application Settings Using the Designer). But in C#, the typical course of action is to use the Designer to create and bind String settings, and add just the one line of code in your form's FormClosing event handler.

Creating and Binding a Setting in One Step
The theme for this article is reducing the effort needed to create persistent settings. And you can reduce the effort even further by both creating and binding a setting in a single step. So this time, select the TextBox from the visual designer, and then select the drop-down of the Text property under the Application Settings item in the Properties pane (see Figure 13). Ignore the fact that we have already set the Text property to PreferredPath.

Figure 13. One-step Setting Creation and Binding: Open the dropdown on the Text property of Application Settings.
Figure 14. New Application Setting Dialog: This dialog appears when you click the "New..." link from the ApplicationSettings dropdown list.
This time, notice the "New…" link near the bottom of the dropdown; when you click that you'll see a New Application Setting dialog (see Figure 14).

The fields should be familiar—name, scope, and value—but here the type field is absent because the value must be a string. If you did not already have the PreferredPath setting defined, you could both create it here and bind it here—all in one dialog. See How to: Add or Remove Application Settings for a nutshell summary on the steps discussed so far.

Additional Binding to Consider
Unfortunately, that easy settings procedure doesn't include everything you might want. For example, one notable component that (oddly) cannot handle automatic settings is a ToolStrip. But fear not! Quoting from Microsoft's Application Settings Overview documentation:

"Custom controls can also save their own settings by ... the SaveSettings method. The Windows Forms ToolStrip control implements this interface to save the position of toolbars and toolbar items between application sessions."
Therefore, if you want to persist toolbar settings for your application, you only need add these bits of code to the FormClosing and Load event handlers:

   private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
      . . .
   private void MainForm_Load(object sender, EventArgs e)
Note that waiting until your program terminates introduces a slight chance that the tool strip settings might not be saved if your program crashes, for example, but the alternative is putting in separate hooks for each event that is fired from a tool strip change. Too much work and too messy, in my view.

This discussion thread is another useful source of information on form size and location saving, as is this article: Saving out a Form's Size and Location using the Application Settings feature

Caveats on Bindings and Settings
The functionality and implementation discussed above fit the ubiquitous 80/20 rule; that is, these techniques will be useful—indeed, valuable—80 percent of the time. To be complete, though, it is important to be aware of limitations of bindings and limitations of settings. Since this falls in the 20 percent bucket, I will just state the issues to be aware of, as reported in MSDN; exploring the depths of these issues is beyond the scope of this article.

First, for bindings, components that you are binding to must have the "right stuff", otherwise they will not quite do what is expected. The MSDN article Application Settings Architecture in the section called "Settings Bindings" describes it this way:

"You can only bind an application setting to a component that supports the IBindableComponent interface. Also, the component must implement a change event for a specific bound property, or notify application settings that the property has changed through the INotifyPropertyChanged interface. If the component does not implement IBindableComponent and you are binding through Visual Studio, the bound properties will be set the first time, but will not update. If the component implements IBindableComponent but does not support property change notifications, the binding will not update in the settings file when the property is changed."
Settings also have restrictions as to what types of objects may be stored. The MSDN article Application Settings describes it thusly:

"Application settings can be stored as any data type that is XML serializable or has a TypeConverter that implements ToString/FromString. The most common types are String, Integer, and Boolean, but you can also store values [such] as Color, Object, or as a connection string."
This is not a major limitation, though. In the sample code above, you saw objects of type string, DateTime, and ArrayList all worked just fine. I picked the DateTime and ArrayList quite at random, not from any careful perusal of what types might or might not work.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date