Currently trying to save settings of last inputted textBox value (e.g. number).
Partially this is working code. However, that code allows to remember last value while closing/opening of Parameter_Form(subForm). In case of closing MainForm (application itself), the last textBox value doesn't retain. Why? The history hasn't record. Also I can't get why the cell 'value' is empty. Please see pic.
private void Parameter_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.textBoxLastValue = textBox1.Text;
Properties.Settings.Default.Save();
}
I've found following stuff. Please see attached pic.
Principally it's that number I've inputted in textBox.
There's no issue within app running and opening/closing subForm.
There's an issue after closing of MainForm.
If you load and save settings manually, you should make sure you load settings in form load event and also save it in form closing event:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = Properties.Settings.Default.Test;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.Test = textBox1.Text;
Properties.Settings.Default.Save();
}
If you are using data binding to settings, then you just need to save when closing.
Related
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();
}
}
}
When the application restarts, Form1() calls LoadSettings() which, when executing textBox1.Text = Properties.Settings.Default.Name, modifies the textBox1.Text property causing the textBox1_TextChanged handler to run. That handler function calls SaveSettings() which then overwrites what had previously been stored in Properties.Settings.Default.Password using what's currently in the textBox2.Text field. Because the application had restarted, textBox2.Text is empty and thus the old value of Properties.Settings.Default.Password was overwritten with an empty string.
Thank you Jimi for helping me locate the user.config file and for his sage advice on what not to do in a textChanged event. I can't see a good reason why you'd need to do something every time a character changes in your textBox either -- makes sense why most applications use an Apply or Save button. Seeing this file change as I step-debugged helped me identify the problem with my code.
Is there a way to get the Text in a TextBox that has an Autocomplete that appends text, but without the part that is appended? I want to use this text in the Textbox_TextChanged-event. This code doesn't work
private void Textbox_TextChanged(object sender, EventArgs e)
{
var t = textbox.Text.Substring(0, textbox.SelectionStart);
}
It seems the TextChanged-event fires when the autocomplete-text is appended, but the selection of the appended text is applied after that.
E.g. if the user types in ho and the autocomplete has an entry house, the textbox contains the text house, but the use is selected and can be overwritten when the user continues typing. I want to get the ho-part, because that is the text the user has typed in, without the use-part, which doesn't come from the user.
Question is some what confusing, I have provide an answer as I understood it.
Text change event fires when you change text in the textbox. You can use suggest instead of appending it
Assume that textbox name is "Textbox1"
private void Textbox1_TextChanged(object sender, EventArgs e)
{
this.Textbox1.AutoCompleteMode =
System.Windows.Forms.AutoCompleteMode.Suggest;
var t = Textbox1.Text;
}
I solved it with a delay, so the textbox has time to apply the selection. This seems to work so far, but could be an issue if the applying of the selection takes longer than the wait-time.
private async void Textbox_TextChanged(object sender, EventArgs e)
{
await Task.Delay(200);
var t = textbox.Text.Substring(0, textbox.SelectionStart);
}
I am hoping someone here can help me, i have a Tabless Control on my windows forms application and basically because the tabs are purposely hidden i have added 2 buttons to each tab "Next" and "Back".
This is the code snippet i have for my "Next" button:
private void nextbutton1_Click(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage3;
this.toolStripStatusLabel8.Text = System.DateTime.Now.ToString();
}
Which works fine, however when i use the exact same theory on the "Back" button it does not work:
private void backbutton1_Click(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabmain;
this.toolStripStatusLabel1.Text = System.DateTime.Now.ToString();
}
So my question is how does one go to a previous tabpage from a button? I have looked through here and tried all of the links that came up but nothing has worked any ideas?
You should use the SelectedIndex property instead of using concrete TabPage instances. This way it will still work when you decide to change the order of the pab pages or add new pages:
private void previousButton_Click(object sender, EventArgs e)
{
if (tabControl1.SelectedIndex > 0)
{
tabControl1.SelectedIndex--;
}
}
private void nextButton_Click(object sender, EventArgs e)
{
if (tabControl1.SelectedIndex < tabControl1.TabCount - 1)
{
tabControl1.SelectedIndex++;
}
}
Since there is no "Tabless" tab control in .NET Framework I can only assume that it works similar to the standard TabControl. If the solution doesn't work you should give us some information about the actual class you use.
BTW: There is no need to repeat the buttons on each page. Why don't you just put the buttons outside the TabControl?
Also: I see that you use a ToolStripStatusLabel to show the current time. Instead of updating it each time the user clicks somewhere add a Timer to your form. Set its Interval to 1000 and handle its Tick event. Update the label there:
private void timer1_Tick(object sender, EventArgs e)
{
toolStripStatusLabel1.Text = DateTime.Now.ToLongTimeString();
}
This way it updates constantly and again there is no need to repeat anything. You need to call timer1.Start() in the form's constructor.
I'm writing a simple WinForms app that parses a text file for correct values, and as it finds an incorrect value, opens up a new form, which displays the incorrect or missing value, with the user being able to input the correct value. I have the problem where, for example, I'll deliberately put two incorrect values in my text file to check, and the form window closes immediately after its opened for the first error,and only stays open for the second error to be fixed.
foreach (string line in lines)
{
string[] items = line.Split('\t').ToArray();
for (int i = 0; i <custIndex.Count; i++)
{
int index = custIndex[i];
Globals.Code = items[index - 1].ToUpper();
if (!CountryList.ContainsKey(Globals.Code) && !StateList.ContainsKey(Globals.Code))
{
form2.textBox1.Text = Globals.Code;
form2.Show();//Shows form2 for user to enter correct input
}
}//inner for
}//inner for each
Here's the form 2 code (form 2 being instantiated at the beginning of the method before the looping):
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
//
private void button1_Click(object sender, EventArgs e)
{
Globals.Code = textBox2.Text;
this.Close();
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
The user is supposed to press the button after entering a new value for Globals.Code (I used a global variable, not sure if that was the most kosher way of doing things).After which the form closes and goes back to Form 1. I think form 2 is being displayed properly with the first error value from the text file, but it immediately opens and closes. Is there a way to keep the window open? I'm sorry if this is convoluted, I'm doing a lot of Winforms and I'm not really an expert on this stuff.
Thanks,
Amanda
Your best bet may be to use a modal dialog, so change form2.Show to form2.ShowDialog.
However, when using a global variable with a loop like that, the global variable will only have the last value put into the form after the loop is complete. If you use the ShowDialog approach, the call will block at that line until the user closes the dialog. After that point you can read the value from the textbox and do something with it.
I have a WinForm with a menu bar, a menu and a menuItem (called BlaBlub).
the menu item has CheckOnClick = True and (ApplicationSettings)->(PropertyBindings)->Checked mapped to the setting SomeBool (type bool, scope user, initial value= false)
the value is read correctly from the settings-file (i use a label to check it and also the menu item gets selected/deselected when I make changes to the file between sessions).
However, using the following code I was not able to open the application, click on the menu item and store the changed value back into file
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.Save();
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = string.Format("Value is: {0}", Properties.Settings.Default.SomeBool);
}
I was able to store the value back into file, using the following code, but since this does not seem to be the idiomatic approach, I still seek some enlightment as to how to do this.
private void blaBlubToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.SomeBool = blaBlubToolStripMenuItem.Checked;
}
You said:
the value is read correctly from the settings-file
However, based on the code presented, that wouldn't be correct because on load you aren't setting the checked state. Instead, I think your testing is showing the initial persisted setting value (being false) is also the default Checked state for the menu item.
Therefore, you should also intialize the control too by adding:
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = string.Format("Value is: {0}", Properties.Settings.Default.SomeBool);
blaBlubToolStripMenuItem.Checked = Properties.Settings.Default.SomeBool;
}
Note: Ordinarily I would tell you to use databinding but you can't because I believe MenuItem's do not support this.