60

I have a ListBox on my Form, I want to save it and load the values when I start the application again.

How can I save a list on PrjName.Properties.Settings.Default?

BrunoLM
  • 97,872
  • 84
  • 296
  • 452

4 Answers4

96

No problem at all! Create a new setting, e.g. "MyListOfStrings", type doesn't matter.

enter image description here

then open settings file in a xml editor

enter image description here enter image description here

your file will look like this:

enter image description here

now change it as shown below and save it

enter image description here

well, that's all, now it will look like that:

enter image description here

and in code:

enter image description here

pr0gg3r
  • 4,254
  • 1
  • 36
  • 27
  • If `MyListOfStrings` is defined this way, can it be accessed with the editor in the Visual Studio IDE? – Codor Oct 27 '14 at 08:59
  • 2
    yes, enter/new line creates a new item in that list – pr0gg3r Oct 27 '14 at 09:06
  • 2
    I'm trying to create a list of System.Windows.Media.Color but I'm getting `the property could not be created from it's default value, there is an error in XML document (1,1)` exception. What might be the problem? I've tried to set default values as strings (Red, Blue...) and using hexadecimal too (#FFFF00FF...) with no success. – Sturm Mar 13 '15 at 10:05
  • #FFFF00FF/Red are strings, System.Windows.Media.Color is a struct (https://msdn.microsoft.com/en-us/library/system.windows.media.color%28v=vs.110%29.aspx) and not serializable - but in Property.Settings you can use only serializable types. Solution A: store your colors as strings like described and use an IValueConverter to convert string to Color, e.g. with (Color)ColorConverter.ConvertFromString("Red");. Solution B: implement your own Color type or struct which is serializable and store that xml instead of string – pr0gg3r Mar 16 '15 at 11:48
  • 11
    hmm, most intriguing... And this worked for you? How remarkable. I found that simply writing the text in the box fails on run-time ` The property 'MyListOfStrings' could not be created from it's default value. Error message: There is an error in XML document (1, 1).` you have to add the serialized list in the settings document like this: `<?xml version="1.0" encoding="utf-16"?> <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <string1> <string2> </ArrayOfString>` – memory of a dream Mar 02 '16 at 14:20
  • My compagny is blocking the images. Can the relevent lines of the xml file be pasted as text in the answer? – Maxter Apr 15 '19 at 18:25
  • 1
    Note that if you are using a list of objects instead of simple a string or int, the `.Save()` method will only work if you modify the list itself (say `.Add` or `.Remove`), if you want to save after you modify the **content** of an object already on the list, just reload the list with itself like so: `Properties.Settings.Default.List = Properties.Settings.Default.List;` before calling `.Save()` and it will work properly. This has to do with how the settings class handles detecting changes to avoid writing the same settings to the disk over and over. – Leo Bottaro Oct 08 '20 at 14:24
  • Does not work in VB.NET, as the XML settings file has to be in C# format (`List`), but then when it regenerates the code file, it takes it verbatim (in C#), so you *CAN* correct it to `List(Of String)` for VB's purposes, but then you can't mess with the settings file or it'll overwrite. Unless there's another workaround for that particular problem? My team supports some legacy apps in VB.NET: "just use C#" is not an acceptable answer for legacy support; we use C# for new apps and this is an excellent tutorial answer for C#. – Tim May 25 '21 at 21:26
  • @pr0gg3r System.NullReferenceException is thrown, while exactly replicating the steps for List, can anyone tell how to avoid this error? – Chandraprakash Aug 26 '21 at 06:05
  • do you know why this method doesn't work for Dictionary type? – Mokhabadi May 27 '22 at 13:06
56

I found out that I can't directly save a List<string> on the application settings, but I saw that I can save a StringCollection.

And here I found out that it's very simple to convert from a StringCollection to a List<string>

var list = stringCollection.Cast<string>().ToList();
Community
  • 1
  • 1
BrunoLM
  • 97,872
  • 84
  • 296
  • 452
  • This approach also works for VB.NET projects as `Dim list = stringCollection.Cast(Of String)().ToList()`; I've got legacy apps to support, and this is very helpful / elegantly simple. I used `ToArray` with `String.Join`, but same difference. – Tim May 25 '21 at 23:46
3

I know this is an older question, but I feel it is noteworthy to add that you can create a custom class that inherits whatever kind of list you want to use and it makes it very simple to set. For example, if you want a List<CustomData>, you could create the class like this:

using System.Collections.Generic;

namespace YourNamespace
{
    public class CustomCollection : List<CustomData>
    {
    }
}

then open the settings like @pr0gg3r suggested and add this in the <Settings> section:

    <Setting Name="SomeSetting" Type="YourNamespace.CustomCollection" Scope="User">
      <Value Profile="(Default)" />
    </Setting>

You won't be able to use the settings designer, unless it's a basic data type like string or int. If you are using a custom data type, you'll have to initialize it on startup before using it, but I find it still looks more elegant than trying to directly use a list in the settings.

Timberwolf
  • 426
  • 4
  • 13
  • 1
    I did this inheritance trick and then clean and rebuild and in the settings designer you can browse to your new custom class and select it there. No need to edit the settings file manually. – Alex Martin May 17 '22 at 16:49
0

When using the natively supported Type System.Collections.Specialized.StringCollection

I used this code:

        System.Collections.Specialized.StringCollection SavedSearchTerms = new System.Collections.Specialized.StringCollection();

        if (Properties.Settings.Default.SavedSearches != null)
        {
            SavedSearchTerms = Properties.Settings.Default.SavedSearches;
        }

        SavedSearchTerms.Add("Any Value");

        Properties.Settings.Default.SavedSearches = SavedSearchTerms;