How to save HashTable in user settings?

In .NET, you can select a hash table as the type to install by users. However, when I save it and retrieve it that way, it doesn't seem to have saved it at all.

Hashtable t = new Hashtable();
t.Add(1,"Foo");
t.Add(2,"Bar");
Properties.Settings.Default.Setting = t;
Properties.Settings.Default.Save();

if(Properties.Settings.Default.Setting != null)
        foreach (DictionaryEntry entry in Properties.Settings.Default.Setting)
        {
            MessageBox.Show(entry.Key + " " + entry.Value);
        }

Why doesn't it serialize it in user settings when I can clearly select this type in Visual Studio? I would understand if this was the case with an unregistered type, such as a dictionary, but in a Hashtable list. How to solve this problem? Simplicity and efficiency in this order have the highest priority for me.

Thank you very much kava


update:

@Joao, . , . , - . , , .

"XMLSetting" XMl, -. , , - -/ xml , , ?

if(string.IsNullOrEmpty(Properties.Settings.Default.XMLSetting))
            {
                Console.WriteLine("Usersettings is empty. Initializing XML file...");
                XmlDocument doc = new XmlDocument();
                XmlElement hashtable = doc.CreateElement("HashTable");
                doc.AppendChild(hashtable);

                GenerateValues(doc, hashtable, "1", "Foo");
                GenerateValues(doc, hashtable, "2", "Bar");

                Properties.Settings.Default.XMLSetting = doc.OuterXml;
                Properties.Settings.Default.Save();
            }
            else
            {
                Console.WriteLine("Retrieving existing user settings...");
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(Properties.Settings.Default.XMLSetting);

                Hashtable hashtable = new Hashtable();

                foreach (XmlNode entry in doc.DocumentElement.ChildNodes)
                {
                    hashtable.Add(int.Parse(entry.FirstChild.InnerText), entry.FirstChild.NextSibling.InnerText);
                }

                foreach (DictionaryEntry entry in hashtable)
                {
                    Console.WriteLine(entry.Key + " " + entry.Value);
                }
            }

private static void GenerateValues(XmlDocument doc, XmlElement hashtable, string skey, string svalue)
        {
            XmlElement entry = doc.CreateElement("entry");
            XmlElement key = doc.CreateElement("Key");
            XmlElement value = doc.CreateElement("Value");
            entry.AppendChild(key);
            entry.AppendChild(value);

            key.AppendChild(doc.CreateTextNode(skey));
            value.AppendChild(doc.CreateTextNode(svalue));

            hashtable.AppendChild(entry);
        }
+5
1

Hashtable XML, . , Settings.settings .

, , App.Config, Hastable, .

. . :

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup 
      name="userSettings" 
      type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section 
        name="ConsoleApplication1.MyCustomSettings" 
        type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
        allowExeDefinition="MachineToLocalUser" 
        requirePermission="false" />
    </sectionGroup>
  </configSections>
  <userSettings>
    <ConsoleApplication1.MyCustomSettings>
      <setting name="MyHashtable" serializeAs="Binary">
        <value></value>
      </setting>
      <setting name="MyBackColor" serializeAs="String">
        <value>Silver</value>
      </setting>
    </ConsoleApplication1.MyCustomSettings>
  </userSettings>
</configuration>

, :

public class MyCustomSettings : ApplicationSettingsBase
{
    private static MyCustomSettings defaultInstance = (
        (MyCustomSettings)
        (ApplicationSettingsBase.Synchronized(new MyCustomSettings())));

    public static MyCustomSettings Default
    {
        get { return defaultInstance; }
    }

    [UserScopedSettingAttribute()]
    [DebuggerNonUserCodeAttribute()]
    [DefaultSettingValueAttribute("Silver")]
    public Color MyBackColor
    {
        get { return ((Color)(this["MyBackColor"])); }
        set { this["MyBackColor"] = value; }
    }

    [UserScopedSettingAttribute()]
    [DebuggerNonUserCodeAttribute()]
    [SettingsSerializeAs(SettingsSerializeAs.Binary)]
    public Hashtable MyHashtable
    {
        get { return ((Hashtable)(this["MyHashtable"])); }
        set { this["MyHashtable"] = value; }
    }
}

Program.cs

class Program
{
    static void Main(string[] args)
    {
        // For the first time no Hastable will exist.
        // Create one with the default values
        if (MyCustomSettings.Default.MyHashtable == null)
        {
            Console.WriteLine("Initializing Hashtable...");

            MyCustomSettings.Default.MyHashtable = new Hashtable();

            MyCustomSettings.Default.MyHashtable.Add(1, "foo");
            MyCustomSettings.Default.MyHashtable.Add(2, "bar");

            MyCustomSettings.Default.Save();
        }

        foreach (DictionaryEntry entry in MyCustomSettings.Default.MyHashtable)
        {
            Console.WriteLine(entry.Key + ": " + entry.Value);
        }

        Console.ReadKey();
    }
}

Update: , , , , . , (XML) (XML).

IDE Settings.settings, App.config.

, , StringDictionary, TypeConverter, .

[TypeConverter(typeof(StringDictionaryTypeConverter))]
public class MyStringDictionary : StringDictionary
{
}

public class StringDictionaryTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(
        ITypeDescriptorContext context, 
        Type sourceType)
    {
        if (sourceType.Equals(typeof(string)))
        {
            return true;
        }

        return base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(
        ITypeDescriptorContext context, 
        Type destinationType)
    {
        if (destinationType.Equals(typeof(string)))
        {
            return true;
        }

        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(
        ITypeDescriptorContext context, 
        CultureInfo culture, 
        object value)
    {
        if (value is string)
        {
            MyStringDictionary sd = new MyStringDictionary();

            XDocument xs = XDocument.Load(new StringReader(value as string));

            foreach (var item in xs.Descendants("entry"))
            {
                sd.Add(item.Element("key").Value, item.Element("value").Value);
            }

            return sd;
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(
        ITypeDescriptorContext context, 
        CultureInfo culture, 
        object value, 
        Type destinationType)
    {
        if (destinationType.Equals(typeof(string)))
        {
            MyStringDictionary sd = value as MyStringDictionary;

            StringBuilder sb = new StringBuilder();

            sb.Append("<entries>");
            foreach (DictionaryEntry item in sd)
            {
                sb.AppendFormat(
                    "<entry><key>{0}</key><value>{1}</value></entry>", 
                    item.Key, 
                    item.Value);
            }
            sb.Append("</entries>");

            return sb.ToString();
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

MyStringDictionary . - , Visual Studio , , , Settings.settings XML ( Open Width) MyStringDictionary.

, .

+12

All Articles