locked
Store a Dictionary of String, String in Settings RRS feed

  • Question

  • Tried browsing but could not find System.Collections.Generic. Of course I can store all of it as a comma delimited string, was hoping there's a better way.


    Friday, March 20, 2020 4:31 AM

Answers

All replies

  • Hi Devon

    I have tried several 'versions' of Dictionary (Specialized.ListDictionary etc) and despite the fact that the collections work during run time, they refuse to be stored in My.Settings.

    Searching reveals that anything implementing IDictionary is refused when saving to My.Settings  -  I don't know the technicallities, but other more knowledgeable members found those results.

    If you can live with using a DataTable instead, that does work in My.Settings.


    Regards Les, Livingston, Scotland

    Friday, March 20, 2020 5:42 AM
  • Tried browsing but could not find System.Collections.Generic. Of course I can store all of it as a comma delimited string, was hoping there's a better way.


    I'm not sure what you meant when you said:

    "Tried browsing but could not find System.Collections.Generic."

    It seems to show up in my web searches. e.g. - 

    System.Collections.Generic Namespace
    https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic?view=netframework-4.8

    Generic collections in .NET
    https://docs.microsoft.com/en-us/dotnet/standard/generics/collections?view=netframework-4.8

    Have you considered something like this?

    Data Storage with PersistentDictionary
    https://github.com/microsoft/ManagedEsent/blob/master/Documentation/PersistentDictionaryDocumentation.md

    https://github.com/microsoft/managedesent

    - Wayne

    Friday, March 20, 2020 7:55 AM
  • Here's the VB sample from the page in my last post:

    ============================
    PersistentDictionary Sample

    Here is an application that remembers a first name -> last name mapping 
    in a persistent dictionary.

    Imports Microsoft.Isam.Esent.Collections.Generic
    
    Module PersistentDictionarySample
    
      Sub Main()
        Dim dictionary As PersistentDictionary(Of String, String) = New PersistentDictionary(Of String, String)("Names")
        Console.WriteLine("What is your first name?")
        Dim firstName As String = Console.ReadLine()
        If dictionary.ContainsKey(firstName) Then
          Console.WriteLine("Welcome back {0} {1}", firstName, dictionary(firstName))
        Else
          Console.WriteLine("I don't know you, {0}. What is your last name?", firstName)
          dictionary(firstName) = Console.ReadLine()
        End If
      End Sub
    
    End Module
    
    ============================

    - Wayne

    Friday, March 20, 2020 8:04 AM
  • Have you considered System.Collections.Specialized.StringDictionary? It can be selected in Settings tab.

    Friday, March 20, 2020 11:46 AM
  • Here is the code I tried:
    Public Class Form1
        Private SD As New Specialized.StringDictionary
    
        Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click
            SD.Clear()
            TextBox1.Clear()
            SD.Add("One", "1")
            SD.Add("Two", "2")
            SD.Add("Three", "3")
            SD.Add("Four", "4")
            SD.Add("Five", "5")
    
            For Each K As String In SD.Keys
                TextBox1.AppendText(K & vbNewLine)
            Next
            TextBox1.AppendText(vbNewLine)
            For Each V As String In SD.Values
                TextBox1.AppendText(V & vbNewLine)
            Next
    
            My.Settings.Test = SD
            My.Settings.Save()
        End Sub
    
        Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click
            SD = My.Settings.Test
            TextBox1.Clear()
            For Each K As String In SD.Keys
                TextBox1.AppendText(K & vbNewLine)
            Next
            TextBox1.AppendText(vbNewLine)
            For Each V As String In SD.Values
                TextBox1.AppendText(V & vbNewLine)
            Next
        End Sub
    
        Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
            SD = My.Settings.Test
            TextBox1.Clear()
            Dim MyEnum As IEnumerator = SD.GetEnumerator()
            Dim De As DictionaryEntry
            While (MyEnum.MoveNext())
                De = DirectCast(MyEnum.Current, DictionaryEntry)
                TextBox1.AppendText(De.Key.ToString & vbTab & De.Value.ToString & vbNewLine)
            End While
        End Sub
    End Class
    
    
    Button 9 & 10 & 11 all work as long as 9 is clicked first
    10 & 11 fail if clicked first (SD is Nothing), it seems it is not being saved properly


    Saturday, March 21, 2020 2:41 AM
  • Here is the code I tried:
    Button 9 & 10 & 11 all work as long as 9 is clicked first
    10 & 11 fail if clicked first (SD is Nothing), it seems it is not being saved properly


    Try this:

    From the Settings sheet, click on the "View Code" tab.

    It should open the file Settings.vb in the IDE.

    It may look something like this:

    Namespace My
    
        'This class allows you to handle specific events on the settings class:
        ' The SettingChanging event is raised before a setting's value is changed.
        ' The PropertyChanged event is raised after a setting's value is changed.
        ' The SettingsLoaded event is raised after the setting values are loaded.
        ' The SettingsSaving event is raised before the setting values are saved.
        Partial Friend NotInheritable Class MySettings
        End Class
    End Namespace
    

    Add the lines shown below to cause serialization to be done as binary rather 
    than as XML.

    Imports System.Configuration Namespace My 'This class allows you to handle specific events on the settings class: ' The SettingChanging event is raised before a setting's value is changed. ' The PropertyChanged event is raised after a setting's value is changed. ' The SettingsLoaded event is raised after the setting values are loaded. ' The SettingsSaving event is raised before the setting values are saved.

    <SettingsSerializeAs(SettingsSerializeAs.Binary)> Partial Friend NotInheritable Class MySettings End Class End Namespace


    Rebuild and run your tests again.

    If you NEED the settings to be in XML rather than binary, you will likely
    have to do it the long way by writing your own persistence.

    Some references, in case you missed them to date:

    StringDictionary not saving as user setting
    https://stackoverflow.com/questions/424010/stringdictionary-not-saving-as-user-setting

    Serialization (Visual Basic)
    https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/concepts/serialization/#binary-and-xml-serialization

    Walkthrough: Persisting an Object in Visual Studio (Visual Basic)
    https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/concepts/serialization/walkthrough-persisting-an-object-in-visual-studio

    SettingsSerializeAsAttribute Class
    https://docs.microsoft.com/en-us/dotnet/api/system.configuration.settingsserializeasattribute?view=netframework-4.8

    - Wayne

    • Marked as answer by Devon_Nullman Sunday, March 22, 2020 1:10 AM
    Saturday, March 21, 2020 6:27 AM
  • Many thanks

    Sunday, March 22, 2020 1:33 AM