How to set checkbox.isChecked without raising event - c#

Is there a way of checking the CheckBox without running the code associated to checking it? Just for visual appearance.
Edit:
private void normalCheck_Checked(object sender, RoutedEventArgs e)
{
normal();
}
Imagine that I want to set the normalCheckBox.IsChecked=true; but without raising the event. Is that possible?

One way would be to detach the event handler, set the IsChecked property, and then reattach it.
myCheckbox.Checked -= myCheckbox_Checked;
myCheckbox.IsChecked = true;
myCheckbox.Checked += myCheckbox_Checked;

You could use the Click event instead of Checked and use the state of the checkbox like below:
private void normalCheck_Click(object sender, RoutedEventArgs e)
{
if (normalCheck.IsChecked ?? false) { normal(); }
}
Then, this event won't be raised by using normalCheck.IsChecked = true;. It will only be raised by a click.
NOTE: The null-coalescing operator (??) is necessary because IsChecked returns a bool? type which could be null.

For Unchecked Event : ( based on the solution of #keyboardP )
myCheckbox.Unchecked -= myCheckbox_Unchecked;
myCheckbox.IsChecked = false;
myCheckbox.Unchecked += myCheckbox_Unchecked;

If you're referring to changing the checked status without raising the "_Checked" event, you will likely have to override the event handler with a param to tell it to skip the event or not.
Related answer: Change Checkbox value without raising event

Related

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

Is there anyway to prevent some event fired before end of another event?

In the code below the SelectionChanged event is fired before the end of RowsAdded,how can I make the Event atomic?
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[1];
dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[1].Selected = true;
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.CurrentRow != null)
{
//Something
}
}
what should i do?
SelectionChanged is fired in the middle of handling RowsAdded because you are causing a SelectionChanged by changing the current cell within dataGridView1_RowsAdded. Adding a row doesn't cause both events to be fired -- you're causing the second event while handling the first one. (In fact, you're probably causing SelectionChanged twice, because both lines in the handler seem to change the selection).
If you don't want dataGridView1_SelectionChanged running while in the RowsAdded handler, you need to either temporarily unsubscribe from the event:
dataGridView1.SelectionChanged -= dataGridView1_SelectionChanged;
// change the selection...
dataGridView1.SelectionChanged += dataGridView1_SelectionChanged;
Or even better, re-design what you're doing inside the SelectionChanged handler so that it is appropriate for all instances of the event.
You can override the event you want to conrol and then put an if condition in the overriden event and control when it fires and when it does not.
mahdi

Reliable Way To Cancel ItemCheck Event On CheckedListBox

Does anyone know of a reliable way to cancel the ItemCheck event on a CheckedListBox? I am in a situation where the ItemCheck event should basically discard changes on a form, however, if the person decides to cancel the discard I would like the ItemCheck event not to fire so as not to change anything.
It is easy to do with the ItemCheck event. Just set the value back. Like this:
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
if (someCondition) e.NewValue = e.CurrentValue;
else {
// Regular stuff
//...
}
}
public void cancelevent()
{
checkedListBox1.ItemCheck -= new ItemCheckEventHandler(this.checkedListBox1_ItemCheck);
}
Call this method any where to cancel the event.
If we += the event will be created and -= will remove the event.
If you want more details please mention. :)

Two Controls Reference One-Another Correctly

I have a ComboBox and a DateTimePicker control in a .net forms application. The desired functionality for the relationship of the two controls is that a modification to one will change the value in the other. Logic to modify the other control is in each controls change event; ComboBox "SelectedIndexChanged" and DateTimePicker "Changed" and it looks something like the following:
othercontrol.value = value;
Is there a clear way I can isolate change events from the respective controls to determine whether they were sent by the UI vs. the other control's change event to head off the loop the current setup will cause?
As I write this I realize I could probably change the other controls value by invoking the change event and passing some variation in the arguments from the corresponding change event instead of simply setting the other control's value.
You can remove the control's eventhandler before settings it's value and add it back immediately after setting the value.
othercontrol.SelectedChanged -= othercontrol_SelectedChanged;
othercontrol.value = value;
othercontrol.SelectedChanged += othercontrol_SelectedChanged;
Try this then.
Ok, it's a bit hacky but this would work:
private bool eventBubbledDate = false;
private bool eventBubbleCombi = false;
protected override MyCombi_OnChange(object sender, eventargs e)
{
if (eventBubbledDate)
{
eventBubbledDate = false;
return;
}
eventBubbleCombi = true;
myDateTime.Value = myCombi.SelectedValue;
}
protected override MyDateTime_OnChange(object sender, eventargs e)
{
if (eventBubbleCombi )
{
eventBubbleCombi = false;
return;
}
// process DateStuff here
// update other control
eventBubbledDate = true;
}
Alternatively, you could use an Enumeration to track state instead of using boolean 'flags' but I think bools are easier to demonstrate.

Modifying ComboBox SelectedIndex Without Triggering Event in C#

My C# application has a comboBox with a SelectedIndexChanged event. Usually, I want this event to fire, but but sometimes I need the event to not fire. My comboBox is an MRU file list. If a file in the list is found to not exist, the item is removed from the comboBox, and the comboBox SelectedIndex is set to zero. However, setting the comboBox SelectedIndex to zero causes the SelectedIndexChanged event to fire, which in this case is problematic because it causes some UIF code to be run in the event handler. Is there a graceful way to disable/enable events for C# form controls? Thanks.
Start the eventhandler method with
ComboBox combo = sender as ComboBox;
if (combo.SelectedIndex == 0)
{
return;
}
If you're issue is with a different eventhandler you could remove the eventhandler's event registration first.
combo.SelectedIndexChanged -= EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;
combo.SelectedIndex = 0;
combo.SelectedIndexChanged += EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;
I have encountered this many times over the years. My solution is to have a class level variable called _noise and if I know I am about to change the index of combo or any other similiar control that fires when the selected index changes, I do the following in code.
private bool _noise;
Here is the code for the control event handler
private void cbTest_SelectedIndexChange(object sender, EventArgs e)
{
if (_noise) return;
// process the events code
...
}
Then when I know I am going to change the index, I do the following:
_noise = true; // cause the handler to ignore the noise...
cbTest.Index = value;
_noise = false; // let the event process again
I'm surprised there isn't a better way of doing this, but this is the way I do it. I actually use the Tag field of most controls so I don't have to subclass the control. And I use true/null as the values, since null is the default.
Of course, if you are actually using Tag, you'll need to do it differently...
In handler:
private void control_Event(object sender, EventArgs e)
{
if (control.Tag != null ) return;
// process the events code
...
}
In main code
try
{
control.Tag = true;
// set the control property
control.Value = xxx;
or
control.Index = xxx;
or
control.Checked = xxx;
...
}
finally
{
control.Tag = null;
}
One (fairly ugly) way would be to set a flag in the code that deletes the entry and then check that in the SelectedIndexChanged handler:
if (!deletedEntry)
{
// Do stuff
}
deletedEntry = false;
A better way might be to remove your SelectedIndexChanged event handler at the start of the delete method and reinstate it at the end. This way you code won't know the index has changed.
There's a better way!
combo_box = QComboBox() # your combobox
combo_box.blockSignals(True)
combo_box.setCurrentIndex(self, ix)
combo_box.blockSignals(False)

Categories