free software, web technologies and heavy metal coding (and ruby of course)

custom application settings

Within a c# winform application I needed to store a generic collection to my settings, which I found out was not possible out of the box. It is possible though to set the required type in the properties designer dialog, but the serialization’s output is always nothing.

On my research on the internet for a solution i stumbled upon the post Tips for C# .NET Software Developers, which described that the attribute [SettingsSerializeAs(SettingsSerializeAs.Binary)] was required for the settings property, and to set it accordingly in the Settings.Designer.cs file. The problem here is that modifying designer generated code file is not the best of all ideas, as the manual changes are overwritten every time the settings are modified by the designer. Thus, I followed the msn article on how to create application settings, which told me to create a custom settings class. The drawback with this solution is that I now have two settings classes, and not only one single to cover it all.

Here’s an example of the settings class. Note the use of the SettingsSerializeAs attribute, as it is the key to the successful serialization.


using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;

namespace Koffeinfrei
{
    /// <summary>
    ///   This class provides extended settings. Use this class for types that need to have special     
    ///   attributes for serialization, that cannot be set using the config designer dialog.
    /// </summary>
    internal class ExtendedSettings : ApplicationSettingsBase
    {
        private static readonly ExtendedSettings defaultInstance =
            ((ExtendedSettings) (Synchronized(new ExtendedSettings())));

        /// <summary>
        ///   Returns the default instance of this class.
        /// </summary>
        /// <remarks>
        ///   Get the value of the <see name="defaultInstance" /> member.
        /// </remarks>
        public static ExtendedSettings Default
        {
            get { return defaultInstance; }
        }

        /// <summary>
        ///   The <see cref="SomeCustomClass" />s stored in the user scoped settings.
        /// </summary>
        /// <remarks>
        ///   Get / set the value of the <c>CustomClasses</c> property.
        /// </remarks>
        [UserScopedSetting]
        [DebuggerNonUserCode]
        [SettingsSerializeAs(SettingsSerializeAs.Binary)]
        public Queue<SomeCustomClass> CustomClasses
        {
            get { return ((Queue<SomeCustomClasses>) (this["CustomClasses"])); }
            set { this["CustomClasses"] = value; }
        }
    }
}

EDIT

Thanks to partial classes you can merge the custom settings to the main settings. Just use the same class name internal class Settings.