简体   繁体   中英

C# - How to save TextBox and CheckBox in User Settings

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;
       }

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://docs.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();
        }

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM