Checkbox not clearing after click event - c#

I have a click event that I run when someone selects a checkbox. I have provided my code below as a reference. The checkbox does not clear after the user selects OK. I clearly set the property to false in the code, and I used breakpoint to make sure it was getting to that point and it was. I even made sure my checkbox was receiving false and it was. What is preventing me from unchecking that box and how should I go about fixing this problem?
private void rChkBoxB_Click(object sender, EventArgs e)
{
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
}
}
}

Can you try executing this code on MouseUp instead of Click

Related

Is the following possible when initiating an if pictureBox clicked event?

I have been trying to make a matching game and I recently learned that the following is possible:
if (checkBox1.checked = true)
{
MessageBox.Show("For Example.")'
}
Then why is the following not possible?
private void pictureBox1_Click(object sender, EventArgs e)
{
MessageBox.Show("Now Pick Another Hidden Picture!");
pictureBox1.Visible = false;
if (pictureBox13.Click = true)
{
MessageBox.Show("Great!");
pictureBox13.Visible = false;
double score = score + 1;
textBox1.Text = (score).ToString();
}
else
{
MessageBox.Show("Try Again!");
pictureBox13.Visible = true;
pictureBox1.Visible = true;
}
}
There is a error line under .Click , and the error is :
The event 'system.Windows.Forms.Control.Click' can only appear on the left hand side of += or -=.
What does this mean? And why does this work for checking checkboxes, but not for clicking pictureboxes? Thank in advance.
Checked is the state of a checkbox. At any given time, a checkbox is either checked or unchecked. Reading myCheckBox.Checked immediately returns the current state of the checkbox.
Click is an event. What do you expect if (pictureBox.Click == true) to do? Tell you if the pictureBox has been clicked within the last X seconds? Wait X seconds for the user to click (or not click) on the pictureBox?
In other words: If you check a checkbox, it stays checked until it is unchecked. Thus, it makes sense to check the current state of the checkbox. On the other hand, if you click a button, it is "clicked" for only an instant and then returns to being "unclicked". Thus, it just does not make sense to query the "clicked" state of a button.
PS: Comparisons are done with ==, not with =. The latter is an assigment. And, as Hugh correctly points out in the comments, if (boolean) is enough, if (boolean == true) is redundant.

Preventing a checkbox Checked event

I have a checkbox on which I want to ask the user if he is sure or I will cancel the operation.
I tried the Click event but it turns out it is only being called after the CheckedChanged event.
I thought I could at least do it "ugly" by asking the user inside the CheckedChanged event but then if he wishes to cancel I need to change the Checked value what raises the event all over again.
Another thing I would prefer to avoid with this solution is that even before the user replies, the tick mark appears in the checkbox.
I'm looking for an event that happens before the CheckedChanged or a way to prevent the CheckedChanged event.
Set AutoCheck to false. and handle the Checked state in the Click event.
Find the Sample Code. It just removes the event attached to the checkbox and adds it back
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
checkBox1.CheckedChanged -= checkBox1_CheckedChanged;
checkBox1.Checked = false;
checkBox1.CheckedChanged += checkBox1_CheckedChanged;
}
}
Adding up to Sievajet's answer.
The AutoCheck property is set to false to prevent automatic update of checkbox's appearance when it is clicked.
See the official documentation of AutoCheck below
Gets or set a value indicating whether the
System.Windows.Forms.CheckBox.Checked
or System.Windows.Forms.CheckBox.CheckState values and the System.Windows.Forms.CheckBox's
appearance are automatically changed when the System.Windows.Forms.CheckBox is
clicked.
Try the ClickEvent Handler Below
private void checkBox_Click(object sender, EventArgs e)
{
if (checkBox.Checked == false)
{
DialogResult result = MessageBox.Show("Confirmation Message", "Confirm",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (result == DialogResult.OK)
{
checkBox.Checked = true;
}
}
else
{
checkBox.Checked = false;
}
}

listView ItemSelectionChanged 'Is Selected' not working as expected?

I'm having a problem with a ListView ItemSelectionChanged event being called twice. From searching I've found it's because the event is being called when an item is selected and again when an item is deselected. I only want it to fire when an item is selected, not when it's deselected. The solution seems to have an if(e.IsSelected) at the beginning of the event so it's only called when an item is selected, but that's not working for me in this case. Here's the basic structure of my code:
private void SelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
DialogResult GetDialogResult =
MessageBox.Show("Keep this item selected?",
"Keep Selected",
MessageBoxButtons.YesNo);
if (GetDialogResult == DialogResult.No)
listView1.SelectedItems[0].Selected = false;
}
}
MultiSelect is disabled so the selected item index will always be 0. My problem is I want the selected item to be deselected if the DialogResult is No, but when you click no, the SelectionChanged event is firing again, and e.IsSelected is apparently still true, so the Dialog Box pops up a second time. I imagine it has something to do with the fact that the first event hasn't completely finished executing when the item is being deselected, but I'm not sure how to solve that and make it so the Dialog Box only shows up once. Any suggestions?
Edit: Something else I've tried now is instead of Deselecting the item in the listBox, clearing all items in the listbox and recreating them. If the items are all cleared, the dialog box doesn't come up a second time. However if the items are immediately recreated, the same item becomes selected again and the dialog box still comes up the 2nd time.
If the behaviour you want is:
User clicks an item
Dialog pops up
If they click 'no' on the popup, selection doesn't happen
If they click 'yes', it does
then one approach is to unhook your event handler before you set the Selected property to false, then rehook afterwards, as follows:
if (GetDialogResult == DialogResult.No)
{
listView1.ItemSelectionChanged -= SelectionChanged;
e.Item.Selected = false;
listView1.ItemSelectionChanged += SelectionChanged;
}
This will stop the event handler from triggering again until your operation has completed.
ItemSelectionChanged (like several other events on other controls) gets fired when you change the value from the program as well. So when you run this line of code, that counts as a "selection changed"...
listView1.SelectedItems[0].Selected = false;
One way to handle this is by setting a flag:
private bool _programChangingSelection;
private void SelectionChanged(object sender, EventArgs e)
{
if (_programChangingSelection)
{
_programChangingSelection = false;
return;
}
if (e.IsSelected)
{
DialogResult GetDialogResult =
MessageBox.Show("Keep this item selected?",
"Keep Selected",
MessageBoxButtons.YesNo);
if (GetDialogResult == DialogResult.No)
{
_programChangingSelection = true;
listView1.SelectedItems[0].Selected = false;
}
}
}
Although, personally I think the add/remove handler method is probably a bit more elegant.
I've found a solution that works. Calling a function to deselect the item asynchronously in a separate thread seems to have solved the issue for me. Without doing this, the second SelectionChanged event is called and has to finish executing before the first one can finished executing, which apparently causes the problem I was seeing. Here is the code I came up with that has worked:
delegate void DeselectDelegate();
public void DeselectItem()
{
if (this.listView1.InvokeRequired)
{
DeselectDelegate del = new DeselectDelegate(DeselectItem);
this.Invoke(del);
}
else
{
listView1.SelectedItems[0].Selected = false;
}
}
private void SelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
DialogResult GetDialogResult =
MessageBox.Show("Keep this item selected?",
"Keep Selected",
MessageBoxButtons.YesNo);
if (GetDialogResult == DialogResult.No)
{
Thread thread = new Thread(DeselectItem);
thread.Start();
}
}
}

Display box showing twice C#

I am performing a validation for my ID field when the user chooses what format it will be. The validation works except for the fact that when it displays the messagebox you select OK, then it repeats once more before going back to the form. I have supplied my code for it below. I used the dialogresult part to see if making it perform an action would stop the problem. This was fixed by using the Click event as mentioned by one of the answers.
private void rChkBoxB_ToggleStateChanged(object sender, Telerik.WinControls.UI.StateChangedEventArgs args)
{
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
}
}
}
The new problem is turning the checkbox back to false after the click event. Here is my updated code. The typical checkbox.checked = false does not change it back to false. I used breakpoint to verify I am getting the to the if statement and the value says false for my checkbox. How can I change the property back to false?
private void rChkBoxB_Click(object sender, EventArgs e)
{
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
}
}
}
Because you've set Checked = false in return of the dialogresult? Hence, toggling the state again?
EDIT: Of note, you are probably using the CheckStateChanged event. So, you check the checkbox (setting it to true), it fires, you show the MessageBox, you set the checkbox back to false, which in turn, causes the event to fire again (you are changing the state).
This is where you could use the Click event, as opposed to setting a flag (proposed solution). That way when you set the checkbox back to false, in code, the Click event won't fire. At runtime, a Click event, for a checkbox, will always toggle the checkbox on/off, no matter where you click on the checkbox.
In conclusion, just use the Click event:
private void rChkBoxB_Click(object sender, EventArgs e)
{
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
}
}
}
Of course, in either version of your code, I'm assuming you want to actually check if Text > 256 when you are checking it to true. So you might want to:
private void rChkBoxB_Click(object sender, EventArgs e)
{
if (rChkBoxB.Checked == false) return; // NEW CODE HERE
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
}
}
}
The code is not the problem, but the event ToggleStateChanged being called more than one time when rChkBoxB.Checked = false;
It run two times because you change the checked property inside the radio button. When you change it the CIL see that it generate a new flag and it does again the event.
For anticipating this you can put a second control in the first if
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256 && rChkBoxB.Checked)
{
///TODO
}
I also suggest to check if the input is correct: in this case you want only int so you can use int.TryParse(string, out int) (see reference here) or you can use Regex (references here)
Problem: ToggleStateChanged event will be fired whenever Checkbox state is being changed. Your checkbox state is getting changed when you set rChkBoxB.Checked = false; that is the reason why your ToggleStateChanged event is invoking twice.
Solution: Take a bool variable and make it true when user selects ok , then even if the ToggleStateChanged event triggers it wont invoke the function twice as isValid is set to true.
bool isValid=false;//declare as class variable
private void rChkBoxB_ToggleStateChanged(object sender, Telerik.WinControls.UI.StateChangedEventArgs args)
{
if(!isValid)
{
if (Convert.ToInt32(rTxtBoxFormatID.Text) > 256)
{
DialogResult dialogresult = MessageBox.Show("B does not support numbering over a number!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (dialogresult == DialogResult.OK)
{
rChkBoxB.Checked = false;
isValid=true;
}
else
{
isValid=false;
}
}
}
else
{
isValid=false;
}
}

Message Box Firing Twice When Editing a CheckBox Cell in a DataGridView

I've got a DataGridView with bound data, but there is a checkbox column that is unbound that I am keeping track of myself. The EditMode is EditProgrammatically. When the user tries to Disable the checkbox, I pop a message box asking them if they are sure they want to disable it. If they choose yes, I disable it. No, I cancel the edit. When they choose yes and I change the value, the message box fires again. Anyone have any idea why this is happening?
Here is the code in question:
private void dgv1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dgv1.BeginEdit(false))
dgv1.EndEdit();
}
private void dgv1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (dgv1.Columns[e.ColumnIndex].Name == "Enabled")
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dgv1.Rows[e.RowIndex].Cells["Enabled"];
if (checkCell.Value.Equals(checkCell.FalseValue))
{
checkCell.Value = checkCell.TrueValue;
}
else
{
DialogResult result = MessageBox.Show(this, "Are you sure you want to Disable this?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
if (result == DialogResult.No)
e.Cancel = true;
else
checkCell.Value = checkCell.FalseValue;
}
}
private void dgv1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
i am not sure why this is happening, maybe you can just show the messagebox on CurrentCellDirtyStateChanged and then call the dgv1.CancelEdit() or CommitEdit() method.
i had a similar situation, where i had to execute code after a checkboxcell changed its value. You can use this code to uncheck it after it was checked.
This way the value is set to true by default checkbox functionality and later you set it back to false if not confirmed. so this is kind of dirty but should work.
void dgv1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dgv1.Columns[e.ColumnIndex].Name == "Enabled")
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dgv1.Rows[e.RowIndex].Cells["Enabled"];
if(!checkCell.Checked)
{
DialogResult result = MessageBox.Show(this, "Are you sure you want to Disable this?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
if (result == DialogResult.No)
{
checkCell.Value = checkCell.TrueValue;
}
}
}
}
the CellValueChanged event is prolly fired too late (as soon as the cell focus is lost). therefore Commit your changes in CellDirtyStateChanged
void dgv1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv1.IsCurrentCellDirty && dgv1.CurrentCell.ColumnIndex == dgv1.Columns["Enabled"].Index)
{
dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit); // raises the cellvaluechangedevent for checkboxes and comboboxes
}
}

Categories