0

I have 2 Windows Forms. In the second form I have a few checkedListBoxex and my problem is that when I'm trying to get those checks and save it for the next time, it's not saving them, maybe I did a small mistake somewhere. I think it should be problem with load.

My code:

public partial class Form2 : Form
    {
        readonly Form1 form1;
        StringCollection collectionOfTags = new StringCollection();
       

        public Form2(Form1 owner)
        {
            form1 = owner;
            InitializeComponent();
            InitializeSecondForm();
            
        }

        private void InitializeSecondForm()
        {
            this.Height = Properties.Settings.Default.SecondFormHeight;
            this.Width = Properties.Settings.Default.SecondFormWidth;
            this.Location = Properties.Settings.Default.SecondFormLocation;
            this.collectionOfTags = Properties.Settings.Default.DICOMTagSettings;

            this.FormClosing += SecondFormClosingEventHandler;
            this.StartPosition = FormStartPosition.Manual;
        }

        private void SecondFormClosingEventHandler(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.SecondFormHeight = this.Height;
            Properties.Settings.Default.SecondFormWidth = this.Width;
            Properties.Settings.Default.SecondFormLocation = this.Location;
            Properties.Settings.Default.DICOMTagSettings = this.collectionOfTags;

            Properties.Settings.Default.Save();
        }

        private void button1_Click(object sender, EventArgs e)
        {
                foreach (string s in checkedListBox1.CheckedItems)
                    Properties.Settings.Default.DICOMTagSettings.Add(s);
             collectionOfTags = Properties.Settings.Default.DICOMTagSettings;

foreach (string s in checkedListBox2.CheckedItems)
                    Properties.Settings.Default.DICOMTagSettings.Add(s);
             collectionOfTags = Properties.Settings.Default.DICOMTagSettings;

foreach (string s in checkedListBox3.CheckedItems)
                    Properties.Settings.Default.DICOMTagSettings.Add(s);
             collectionOfTags = Properties.Settings.Default.DICOMTagSettings;
             this.Close();
            }

This is how it looks in settings.

enter image description here

This one I added just by typing it.

enter image description here

When I'm debugging, I can see that I have some items there, but it's not saving them there.

enter image description here

Sanktos
  • 51
  • 8
  • Did you add said Properties in default settings file of your project. Pl see this also: https://stackoverflow.com/questions/1873658/net-windows-forms-remember-windows-size-and-location/1873713 – Zeeshanef Oct 25 '21 at 10:31
  • 1) Are you sure you're clicking `button1` before closing the form? Because that's the only place where you're saving the checked items. 2) Are you using `collectionOfTags` somewhere to update the checked items when the form is re-opened? Because you're not showing that anywhere in your code. – 41686d6564 stands w. Palestine Oct 25 '21 at 10:31
  • @Zeeshanef I put in Settings.settings DICOMTagSettings like System.Collections.Specialized.StringCollection. – Sanktos Oct 25 '21 at 10:37
  • @41686d6564 1) I'm sure about this button. 2) collectionOfTags = Properties.Settings.Default.DICOMTagSettings - I am putting in this collection and then I'm trying to save it. Like: this.collectionOfTags = Properties.Settings.Default.DICOMTagSettings; and Properties.Settings.Default.DICOMTagSettings = this.collectionOfTags;. I'm not sure that this is the right way. – Sanktos Oct 25 '21 at 10:39
  • _"This is how it looks in settings"_ And it's how it's supposed to look. Saved items don't appear there (in case you were expecting that). To determine whether or not the items are saved, you need to examine the `DICOMTagSettings` collection at run-time while debugging. – 41686d6564 stands w. Palestine Oct 25 '21 at 11:25
  • I made debugging, but still, it didn't help or maybe I missed something. Cause I show everything that I have in this piece of code. – Sanktos Oct 25 '21 at 11:49
  • @Sanktos They _are_ being saved; you just can't see them in the Settings window as I said above. You said that you added the items to the CheckedListBoxes manually by typing them. However, you're only saving the checked items. So, how do you expect to find all the items in the list boxes when you open the form the next time if you didn't save them in the first place? Do you want to restore all the items or just the checked ones? – 41686d6564 stands w. Palestine Oct 25 '21 at 12:17
  • Yeah, you are right, but this is my problem, I don't know how to do it. I would like to put checks in this box and for the next time, when I will close and open it again it should show me what I checked in the last time, but didn't hide others. – Sanktos Oct 25 '21 at 12:21

2 Answers2

2

The checked items are being saved to Properties.Settings.Default.DICOMTagSettings, then, they're being loaded to collectionOfTags, but you're not actually using collectionOfTags to update the checked items.

The collectionOfTags variable is redundant actually (unless you need it for something else). You could just access the string collection directly from settings. Change your code to something like the following.

To save the checked items:

Properties.Settings.Default.DICOMTagSettings.Clear();
foreach (string s in checkedListBox1.CheckedItems)
{
    Properties.Settings.Default.DICOMTagSettings.Add(s);
}

Or you could replace the foreach loop above with this one liner:

Properties.Settings.Default.DICOMTagSettings
    .AddRange(checkedListBox1.CheckedItems.Cast<string>().ToArray());

To update the checked items when the form loads:

foreach (string s in Properties.Settings.Default.DICOMTagSettings)
{
    int index = checkedListBox1.Items.IndexOf(s);
    if (index != -1) checkedListBox1.SetItemChecked(index , true);
}
  • I tried with your solution and got a few errors. 1) Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable' to 'string[]'. It was Properties.Settings.Default.DICOMTagSettings.AddRange(checkedListBox1.CheckedItems.Cast()); 2) When I'm trying to do this one foreach (string s in Properties.Settings.Default.DICOMTagSettings) { checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(s), true); } I'm getting error. Error: System.ArgumentOutOfRangeException: 'InvalidArgument=Value of '-1' is not valid for 'index'. – Sanktos Oct 25 '21 at 11:01
  • @Sanktos 1) My bad. It should be converted to an array. Fixed. 2) You need to show us how you're filling the CheckedListBox items. Are you sure they're all strings? Please [edit](https://stackoverflow.com/posts/69706395/edit) the question and provide a [repro]. – 41686d6564 stands w. Palestine Oct 25 '21 at 11:08
  • Yeah, the first one is working now. I will add more. – Sanktos Oct 25 '21 at 11:13
  • 1
    @Sanktos You edited the question but you didn't show how you fill (i.e., add items to) the CheckedListBox. Please do so. That said, it seems you've been filling the StringCollection with items from multiple CheckedListBoxes, not just one. This could be the cause for the ArgumentOutOfRangeException. The edit I made to the answer above (last code block) _might_ fix the problem but I can't know for sure until I see how you add items to the list boxes. – 41686d6564 stands w. Palestine Oct 25 '21 at 11:22
  • Now I don't have any errors, but when I'm closing the second form it's not saving anything. It should save checks in checkedListBox, but still not. – Sanktos Oct 25 '21 at 11:22
  • Please edit the question and provide a [repro] (click on the link and read the article to know how to create one). The example should include how you add items to the CheckedListBoxes as I said above. – 41686d6564 stands w. Palestine Oct 25 '21 at 11:24
0

I created a method:

private void LoadSettings() 
{
  for (int i = 0; i < checkedListBox1.Items.Count; i++)
        {
            var d = checkedListBox1.Items[i];
            if (collectionOfTags.Contains(d.ToString()))
            {
                int index = checkedListBox1.Items.IndexOf(d);
                if (index != -1)
                    checkedListBox1.SetItemChecked(index, true);
            }
        }
}

Put this method in Constructor:

public Form2(Form1 owner)
        {
            form1 = owner;
            InitializeComponent();
            InitializeSecondForm();

            LoadSettings();

        }

Now it's working, thank you for the help @41686d6564.

Sanktos
  • 51
  • 8