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.