This is just for demo purposes. I will not actually cache passwords this way as I've received advice that Application Settings is not secure.
Problem Statement
I'm creating a login Windows Forms application that persists the string values entered into the Name
and Password
fields between application sessions using Application Settings. The form should load the Name
and Password
values that was entered from the previous session.
I ran into a problem where the fields fail to get saved and reloaded if I use Properties.Settings.Default.Save() to save those field values from a private method:
// Save the current values of each field
private void SaveSettings()
{
Properties.Settings.Default.Name = textBox1.Text;
Properties.Settings.Default.Password = textBox2.Text;
Properties.Settings.Default.Save();
}
When the field values change, this is how `SaveSettings() would be called:
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Name' field.
private void textBox1_TextChanged(object sender, EventArgs e)
{
SaveSettings();
UpdateRichTextbox();
}
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Password' field.
private void textBox2_TextChanged(object sender, EventArgs e)
{
SaveSettings();
UpdateRichTextbox();
}
UpdateRichTextbox()
simply writes Name
and Password
to a rich text box in a formatted manner so that I can see their values:
// Writes current values of each setting to Rich Textbox
private void UpdateRichTextbox()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Name: {Properties.Settings.Default.Name}");
sb.AppendLine($"Password: {Properties.Settings.Default.Password}");
richTextBox1.Text = sb.ToString();
}
Attempt
I made sure to set the scope for both Name
and Password
setting in Project Settings to 'User'. I tried calling Properties.Settings.Default.Upgrade() after .Save().
Name
and Password
persisted when I moved the content of SaveSettings()
to the callbacks invoked when those fields are changed:
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Name' field.
private void textBox1_TextChanged(object sender, EventArgs e)
{
Properties.Settings.Default.Name = textBox1.Text;
Properties.Settings.Default.Save();
UpdateRichTextbox();
}
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Password' field.
private void textBox2_TextChanged(object sender, EventArgs e)
{
Properties.Settings.Default.Password = textBox2.Text;
Properties.Settings.Default.Save();
UpdateRichTextbox();
}
I'm not sure why my first approach didn't work. How did the API devs intend for .Save()
to be used?
Full Example
using System;
using System.Text;
using System.Windows.Forms;
namespace LoginForm
{
public partial class Form1 : Form
{
// Called initially when the form application starts up
public Form1()
{
InitializeComponent();
LoadSettings();
}
// Load saved values to their respective field textboxes
private void LoadSettings()
{
textBox1.Text = Properties.Settings.Default.Name;
textBox2.Text = Properties.Settings.Default.Password;
}
// Writes current values of each setting to Rich Textbox
private void UpdateRichTextbox()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Name: {Properties.Settings.Default.Name}");
sb.AppendLine($"Password: {Properties.Settings.Default.Password}");
richTextBox1.Text = sb.ToString();
}
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Name' field.
private void textBox1_TextChanged(object sender, EventArgs e)
{
Properties.Settings.Default.Name = textBox1.Text;
Properties.Settings.Default.Save();
UpdateRichTextbox();
}
// Saves ALL field values in the form whenever the field changes.
// Warning: This function gets called each time a character is added to the 'Password' field.
private void textBox2_TextChanged(object sender, EventArgs e)
{
Properties.Settings.Default.Password = textBox2.Text;
Properties.Settings.Default.Save();
UpdateRichTextbox();
}
}
}