Compartilhar via


Saving Form Settings

Like many developers at Microsoft, I spend a good chunk of my free time writing tools, or fun little programs that use some new SDK, or even applications requested by friends or family to help them do some task better and/or faster.  Many of these materialize as Windows Forms applications simply because System.Windows.Forms makes it very easy to quickly throw together a quality interface with very little code driving it.  A large majority of these UIs have textboxes that store paths to files or directories, checkboxes that store yes/no preferences, etc, and I end up writing one-off methods to load and store these settings to the registry, or to isolated storage, or to an XML file, or to some other store for maintaining state between executions.  Tonight, I got tired of wasting those two minutes for each app and hacked together a simple class to work with 90% of the WinForms tools I write.

public class SettingsSaver

{

    private static string _settingsKey = @"Software\Toub";

 

    public static string SettingsKey { get { return _settingsKey; } set { _settingsKey = value; } }

 

    public static void Register(Form f)
    {

        if (f != null)

        {

            f.Load += new EventHandler(LoadSettings);

            f.Closing += new System.ComponentModel.CancelEventHandler(SaveSettings);

        }

    }

 

    private static void LoadSettings(object sender, EventArgs e) 
    {

        Form f = sender as Form;

        if (f == null) return;

        try

        {

            using (RegistryKey parentKey = Registry.CurrentUser.OpenSubKey(_settingsKey, false))

            {

                if (parentKey != null)

                {

                    using (RegistryKey key = parentKey.OpenSubKey(Assembly.GetEntryAssembly().GetName().Name))

                    {

                        if (key != null) LoadSettings(key, f);

                    }

                }

            }

        }

        catch(Exception exc)

        {

            Debug.Write(exc.ToString());

     }

    }

 

    private static void LoadSettings(RegistryKey key, Control parent)

    {

        foreach(Control c in parent.Controls)

    {

            if (c is CheckBox) ((CheckBox)c).Checked = bool.Parse((string)key.GetValue(c.Name, ((CheckBox)c).Checked.ToString()));

            else if (c is TextBox) ((TextBox)c).Text = (string)key.GetValue(c.Name, ((TextBox)c).Text);

            else if (c is RadioButton) ((RadioButton)c).Checked = bool.Parse((string)key.GetValue(c.Name, ((RadioButton)c).Checked.ToString()));

            else if (c is TrackBar) ((TrackBar)c).Value = int.Parse((string)key.GetValue(c.Name, ((TrackBar)c).Value.ToString()));

            else if (c.Controls.Count > 0) LoadSettings(key, c);

     }

    }

 

    private static void SaveSettings(object sender, System.ComponentModel.CancelEventArgs e)

    {

        Form f = sender as Form;

        if (f == null) return;

        try

        {

            using (RegistryKey parentKey = Registry.CurrentUser.CreateSubKey(_settingsKey))

            {

                using (RegistryKey key = parentKey.CreateSubKey(Assembly.GetEntryAssembly().GetName().Name))

                {

                    if (key != null) SaveSettings(key, f);

     }

     }

        }

        catch(Exception exc)

        {

            Debug.Write(exc.ToString());

     }

    }

 

    private static void SaveSettings(RegistryKey key, Control parent)
    {

        foreach(Control c in parent.Controls)

        {

           if (c is CheckBox) key.SetValue(c.Name, ((CheckBox)c).Checked.ToString());

           else if (c is TextBox) key.SetValue(c.Name, ((TextBox)c).Text);

            else if (c is RadioButton) key.SetValue(c.Name, ((RadioButton)c).Checked.ToString());

            else if (c is TrackBar) key.SetValue(c.Name, ((TrackBar)c).Value.ToString());

            else if (c.Controls.Count > 0) SaveSettings(key, c);

        }

    }

}

Now when I write an app, all I need to do is add the following line to my Form's constructor:
        SettingsSaver.Register(this);
and all of the settings for my form wil be automatically loaded when it's opened and saved when it's closed.

Comments

  • Anonymous
    April 01, 2004
    Nicely done! Thanks a lot for this, it is going to save me a lot of time :-P

    Incedently, if anyone wants to use this code in a class, they will need to use the following namespaces...

    using System;
    using System.Windows.Forms;
    using System.Reflection;
    using System.Diagnostics;
    using Microsoft.Win32;

    (just in case ppl get stuck)

    Regards
    KevinT
  • Anonymous
    June 17, 2005
    I want to save setting like your suggested in your class, but I want a checkbox on the messagebox to ask the user to save the setting. Something like never asked this question again...

    How do you add this?
  • Anonymous
    June 17, 2005
    The comment has been removed
  • Anonymous
    March 10, 2006
    The comment has been removed