2

I have a Windows Form Application, where the User can input numbers into three different TextBoxes. I want to save these numbers by checking the Checkbox next to it, so when the Application gets closed and re-opened you don't have to put in the numbers again.

I have added the Properties to the User Settings and implemented the Code below, but when I input a number and re-open the Application, nothing is shown and they aren't saved in the user.config file.

Any help is greatly appreciated as I can't find my mistake.

       private void MainForm_Load(object sender, EventArgs e)
       {
           Text = Properties.Settings.Default.title;
           chkBox1.Checked = Properties.Settings.Default.checkBox;
           chkBox2.Checked = Properties.Settings.Default.checkBox;
           chkBox3.Checked = Properties.Settings.Default.checkBox;
           txtBox1.Text = Properties.Settings.Default.textBox;
           txtBox2.Text = Properties.Settings.Default.textBox;
           txtBox3.Text = Properties.Settings.Default.textBox;
           this.Location = new System.Drawing.Point(Properties.Settings.Default.PX, Properties.Settings.Default.PY);
       }
       private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
       {
           Properties.Settings.Default.checkBox = chkBox1.Checked;
           Properties.Settings.Default.checkBox = chkBox2.Checked;
           Properties.Settings.Default.checkBox = chkBox3.Checked;
           Properties.Settings.Default.textBox = txtBox1.Text;
           Properties.Settings.Default.textBox = txtBox2.Text;
           Properties.Settings.Default.textBox = txtBox3.Text;
           Properties.Settings.Default.PX = this.Location.X;
           Properties.Settings.Default.PY = this.Location.Y;
           Properties.Settings.Default.Save();

       }

       private void chkBox1_Checked(object sender, EventArgs e)
       {
           this.Text = txtBox1.Text;
       }

       private void chkBox2_Checked(object sender, EventArgs e)
       {
           this.Text = txtBox2.Text;
       }

       private void chkBox3_Checked(object sender, EventArgs e)
       {
           this.Text = txtBox3.Text;
       }

Adam Benson
  • 7,480
  • 4
  • 22
  • 45
Lisa Maria
  • 27
  • 1
  • 5
  • _"and they aren't saved in the user.config file"_ [They're not stored in the app.config file](https://stackoverflow.com/a/982397/8967612). You should be able to restore them when the app restarts though. Assuming you didn't move the application and didn't change the version number. – 41686d6564 stands w. Palestine Aug 18 '20 at 09:02
  • 2
    Hi, did you notice that you are saving all three of you textboxes and checkboxes states into the same configuration property ? What that means is that if any of the later saved states are empty, you are clearing what you just tried to save ! (ie : toto in textbox1, and empty in textbox2, means that the saved value will be empty) – Irwene Aug 18 '20 at 09:04
  • ^ Oh, and that. I didn't even notice. – 41686d6564 stands w. Palestine Aug 18 '20 at 09:06
  • Oh and with the code you have right now, the checkboxes don't do anything regarding saving the values into the settings. I'm reproducing yuor scenario to make sure of what i'll write in an answer, but you'll need to expand a little bit on your code to acheive your objective. – Irwene Aug 18 '20 at 09:21
  • @Lisa Maria If one of the provided answers gave you the solution you were looking for, you can indicate so by clicking the tick under the question score :). If not, don't hesitate to comment under the answers or to edit your question. – Irwene Aug 21 '20 at 08:26

2 Answers2

3

Why not use databinding to save changes automatically. You don't need to replicate the code on form_load and form_closing events.

The best explanation I have for control data binds is that they provide two way model update between a control properties and object properties. More Info https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.databindings?view=netcore-3.1

private void Form1_Load(object sender, EventArgs e)
        {
            chkBox1.DataBindings.Add("Checked", Properties.Settings.Default, "Checked1",true, DataSourceUpdateMode.OnPropertyChanged);
            chkBox2.DataBindings.Add("Checked", Properties.Settings.Default, "Checked2",true, DataSourceUpdateMode.OnPropertyChanged);
            chkBox3.DataBindings.Add("Checked", Properties.Settings.Default, "Checked3",true, DataSourceUpdateMode.OnPropertyChanged);
             //you can others
          
            
        }
       
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //don't forget to call save on form closing
            Properties.Settings.Default.Save();
        }
Ikenna Emman
  • 153
  • 1
  • 8
  • That is a great solution, but maybe a little confusing if the OP just started. It might be good to add a little bit about what a binding is, and how it's working to avoid the obvious gotchas that come with them. – Irwene Aug 18 '20 at 09:39
  • And I'll just add that while the solution is elegant, you miss part of the question, being : "only save the textbox when the corresponding checkbox is checked" – Irwene Aug 18 '20 at 09:49
1

The first part of my answer, regarding to the fact that nothing is saved when you close your application, is based on the assumption that when testing, you leave the third textbox empty

Why is nothing saved

First is why you are seeing nothing when opening your application, leading you to believe nothing was saved when closing it.

You are in the part of your code handling what happens when your application is closing, saving all of the textboxes (and checkboxes states) in the same setting

Which leads to the following txtBox1 contains a txtbox2 contains nothing (or an empty string if you prefer)

When saving, what is happening with your code is that in a first step, you are putting "a" into your textbox setting.

Then, you are replacing this vlue with the content of the second textbox, which is empty

(repeat for the third textbox)

The you are saving.... An empty value.

If you wish to fix this in a "naive" way, you would need a setting per textbox and checkbox.

Which would lead to code ressembling this in your Closing event handler

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
   {
       Properties.Settings.Default.checkBox1 = chkBox1.Checked;
       Properties.Settings.Default.checkBox2 = chkBox2.Checked;
       Properties.Settings.Default.checkBox3 = chkBox3.Checked;
       Properties.Settings.Default.textBox1 = txtBox1.Text;
       Properties.Settings.Default.textBox2 = txtBox2.Text;
       Properties.Settings.Default.textBox3 = txtBox3.Text;
       Properties.Settings.Default.PX = this.Location.X;
       Properties.Settings.Default.PY = this.Location.Y;
       Properties.Settings.Default.Save();
   }

Why do I say "naive", because as you've surely understood, this approach is not sustainable for a huge number of controls, but this is not the scope of the question, I'll let you research a solution on your own for this particular point.

Why are the checkbox doing nothing to determine what is saved

First, with the events available on Winforms (at least with the .NET Framework 4.5 which I used to reproduce what you had) the only events available to be notified of the checkbox state change are :

  • CheckedChanged
  • CheckStateChanged

The first is used on a binary Checkbox (checked or not) The second on a checkbox with an uncertain state added to both of the other states.

I imagine you used the first of the two (because that is the one used by default by Visual Studio when double clicking on it in the designer).

The first issue here is that it notifiesyou that the state changed not only that it went from unchecked to checked, but the other way around too.

That means if you only want an action to be done when checking, you need to add a.... check (an if block) to skip the cases you're not interest into.

Next is the actual saving.

What you are doing in your code is just copying the textbox values in a property in your class, and that will NOT persist after closing the application.

Now there is two approach you could use to save those values into the settings, the first is to do it as soon as you check the boxes.

What you would need to do then is for each event handler to copy the value of the textbox.... directly into the settings

An example for the first textbox and checkbox :

private void chkBox1_Checked(object sender, EventArgs e)
{
    if(chkBox1.Checked)
    {
        Properties.Settings.Default.checkBox1 = chkBox1.Checked;
    }
}

I'm not a huge fan though, and would prefer the second solution => to check in the closing event, before copying the value from the textbox into the settings, if the corresponding checkbox is closed.

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (this.chkBox1.Checked)
        {
            Properties.Settings.Default.textBox = txtBox1.Text;
        }
        [...]
    }

Now that a little better, and should be working as intended.

Please note that this answer is oriented towards correcting the problem whilst using solutions that are the closest possible of your original code.

Irwene
  • 2,807
  • 23
  • 48