Reputation:
I want a message box to appear to let the user know when they uncheck a checkbox they will lose the values in two related textboxes. The problem is when the user clicks 'cancel' the message box appears again. In the event a user does click cancel I want the checkbox to remained checked.
if (checkBox1.Checked == false)
{
checkBox2.Checked = false; checkBox3.Checked = false;
checkBox4.Checked = false; checkBox5.Checked = false;
checkBox6.Checked = false; checkBox7.Checked = false;
checkBox8.Checked = false;//Disable preceeding checkboxes
enableAllAssessmentsToolStripMenuItem.Checked = false;
}
if (checkBox1.Checked == true)
{
//Check if checkbox has been checked
textBox1.Enabled = true; textBox2.Enabled = true;//Enable that Line's Textboxes
}
else
{
//Or not
textBox1.Enabled = false; textBox2.Enabled = false;//Disable that Line's Textboxes
}
if(textBox1.Text.Length != 0 || textBox2.Text.Length != 0)
{
//If associated textboxes contain text
DialogResult Result1 = MessageBox.Show("The numbers you have input on this row will be lost", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (Result1 == DialogResult.OK)
{
textBox1.Text = "";
textBox2.Text = "";
}
else if (Result1 == DialogResult.Cancel)
{
checkBox1.Checked = true;
}
}
Upvotes: 1
Views: 992
Reputation: 236208
I believe you have this code in CheckedChanged
handler of checkBox1
. If current state of checkBox1
is not checked, then you are changing it's state when user cancels message box, and you are executing this handler again.
If handler is subscribed you cannot avoid it's executing when state of checkbox is changed. But you can unsubscribe handler:
checkBox1.CheckedChanged -= checkBox1_CheckedChanged;
checkBox1.Checked = true;
checkBox1.CheckedChanged += checkBox1_CheckedChanged;
Or use some boolean flag to indicate this case:
void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (shouldNotHandle)
return;
// ...
else if (Result1 == DialogResult.Cancel)
{
shouldNotHandle = true;
checkBox1.Checked = true;
shouldNotHandle = false;
}
}
Or (maybe better solution) you should re-consider your logic.
I think better solution will be setting AutoCheck
of this checkbox to false
and subscribing to Click
event instead of CheckedChanged
. That will allow you manually change state of checkbox according to conditions:
private void checkBox1_Click(object sender, EventArgs e)
{
checkBox1.Checked = !checkBox1.Checked;
if (textBox1.Text.Length != 0 || textBox2.Text.Length != 0)
{
if (UserConfirmedWarning("Numbers will be lost"))
{
textBox1.Text = "";
textBox2.Text = "";
}
else
{
checkBox1.Checked = true;
}
}
if (!checkBox1.Checked)
DisablePreceedingCheckboxes();
SetLineTextboxesEnabled(checkBox1.Checked);
}
I also extracted some code to other methods:
private void DisablePreceedingCheckboxes()
{
checkBox2.Checked = false;
checkBox3.Checked = false;
// ...
}
private void SetLineTextboxesEnabled(bool enabled)
{
textBox1.Enabled = enabled;
textBox2.Enabled = enabled;
}
private bool UserConfirmedWarning(string message)
{
return MessageBox.Show(message, "Warning",
MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK;
}
Upvotes: 2
Reputation: 5890
This is happaning because you're setting Checked property to true when user clicks Canclec in the messagebox. This fires the CheckedChanged event again.
If you need this checkbox to be checked, simply use a "flag" and set it to true after Cancel is pressed to block the event to be fired.
Something like this:
if (flag) return;
if (checkBox1.Checked == false)
{
checkBox2.Checked = false; checkBox3.Checked = false;
checkBox4.Checked = false; checkBox5.Checked = false;
checkBox6.Checked = false; checkBox7.Checked = false;
checkBox8.Checked = false;//Disable preceeding checkboxes
enableAllAssessmentsToolStripMenuItem.Checked = false;
}
if (checkBox1.Checked == true)
{
//Check if checkbox has been checked
textBox1.Enabled = true; textBox2.Enabled = true;//Enable that Line's Textboxes
}
else
{
//Or not
textBox1.Enabled = false; textBox2.Enabled = false;//Disable that Line's Textboxes
}
if(textBox1.Text.Length != 0 || textBox2.Text.Length != 0)
{
//If associated textboxes contain text
DialogResult Result1 = MessageBox.Show("The numbers you have input on this row will be lost", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
if (Result1 == DialogResult.OK)
{
textBox1.Text = "";
textBox2.Text = "";
}
else if (Result1 == DialogResult.Cancel)
{
flag = true;
checkBox1.Checked = true;
flag = false;
}
}
Upvotes: 2
Reputation: 5380
Since you are calling from within the CheckChanged event handler, and if this is really what your logic imposes, then I'd use a boolean variable as a flag to avoid calling the code twice.
bool setFromHandler = false;
...
setFromHandler = true;
checkBox1.Checked = true;
...
if(setFromHandler)
{
...
}
else
{
...
}
Cheers
Upvotes: 2