Preventing a checkbox Checked event - c#

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

Related

Visual Studio, Devexpress- set button click event to do nothing

I want to click on the editor button and for it to do nothing. I still want to keep it enabled though. I tried for hours, any suggestions?
Automatically, clicking the button will allow the dropdownlist to come up. I want it to be when I click the button, nothing happens.
private void LookUpEdit1_ButtonClick(object sender, ButtonPressedEventArgs e)
{
// code here
}
Handle the QueryPopUp event. In the event handler, set the e.Cancel parameter to True.
private void LookUpEdit1_QueryPopUp(object sender,
System.ComponentModel.CancelEventArgs e) {
ComboBoxEdit combo = sender as ComboBoxEdit;
e.Cancel = true;
}

How to bind the Enabled property of a button in Winforms to the CheckedItems.Count property of a CheckedListBox

I have a CheckedListBox in a form. Each item represents an email message subject of a logged in user.
What I try to achieve is that when only one item is selected, both the Edit and Delete buttons should be enabled, otherwise disabled.
I have tried to use the following event handler after setting the CheckOnClick property to true, but it's not working:
private void clbEmailsSubjects_Click(object sender, EventArgs e)
{
btnEdit.Enabled = btnDelete.Enabled = (clbEmailsSubjects.CheckedItems.Count == 1);
}
Any suggestions?
Edit:
I had selected an item, but both buttons were still disabled.
Now, after selecting the second item they have become enabled:
The effect seems to be contrary. I think the value of CheckedItems.Count might be updated after the event_handler is executed.
It would be more correct to use the ItemCheck event than the Click event (as the click may not have landed on a checkbox). But either way, the event gets fired before the Checked property on the CheckBox gets changed, so you can't set the enabled states within either of those event handlers. You can, however, defer the handling until events are processed using BeginInvoke, like this:
private void clbEmailsSubjects_ItemCheck(object sender, ItemCheckEventArgs e)
{
BeginInvoke((Action)(() =>
{
btnEdit.Enabled = btnDelete.Enabled =
(clbEmailsSubjects.CheckedItems.Count == 1);
}));
}
You need to register for the ItemCheck event on your CheckedListBox. Then the following code will give you the desired result:
private void clbEmailsSubjects_ItemCheck(object sender, ItemCheckEventArgs e)
{
btnEdit.Enabled = btnDelete.Enabled =
(clbEmailsSubjects.CheckedItems.Count == 2 && e.NewValue == CheckState.Unchecked) ||
(clbEmailsSubjects.CheckedItems.Count == 0 && e.NewValue == CheckState.Checked);
}

Setting myButton.Enabled = true causes radiobutton's CheckedChanged handler to fire

I have absolutely no programmatic links or properties set such that my CheckedChanged fires as a result of anything except checking the radio button.
However, when I click a different, unrelated button, the button's click handler fires (this is expected). In this click handler, the button disables itself (it re-enables on a different button's click), which then triggers myRadioButton_CheckedChanged handle for an unrelated radiobutton fires.
The call stack that I'm seeing is essentially
myRadioButton_CheckedChanged (...)
myButton_Click(...)
Main(...)
The line in myButton_Click that is triggering the myRadioButton_CheckedChanged is apparently
myButton.Enabled = false;
The related code is:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
// L-R
if (radioButton1.Checked == true)
{
orientation_left = 3;
pictureBox2.Invalidate();
Debug.Print("left {0}", orientation_left);
}
}
private void select1_Click(object sender, EventArgs e)
{
Debug.Print("select1click");
if (select1Down == false)
{
// ... stuff
select1.Enabled = false; // Causing the CheckedChanged to fire
select2.Enabled = false;
select1Down = true;
}
}
Ok, got it.
Check the TabOrder on your Button and RadioButton.
Seems that when you disable the Button, the focus is shifted to the next control, which is probably your RadioButton, causing it to become checked.
On my test From, all I had to do was to make sure that the RadioButton's TabOrder was not right after the Button.
Cheers
EDIT:
This seems to be a known problem as I just found this MSDN thread: http://social.msdn.microsoft.com/Forums/windows/en-US/77fbec3b-1f63-42e1-a200-19b261b63794/the-radiobutton-clicked-event-is-fired-without-the-radio-button-beeing-clicked-?forum=winforms
Okay, it's kinda hacky but it works without changing anything to the tab order:
private void select1_Click(object sender, EventArgs e)
{
if (!select1Down)
{
// ... stuff
SendKeys.SendWait("{Tab}");
select1.Enabled = false;
select2.Enabled = false;
select1Down = true;
}
}

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

LostFocus handling issue

I want to handle LostFocus event of TextBox to perform some actions. But I'm also wouldn't want to perform that actions if TextBox lost it focus because special Button (which opens OpenFileDialog) was clicked or Key.Enter was catched. When Key.Enter was pressed, first of all KeyDown event is raised. Here my event handler of KeyDown:
public void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e != null && sender != null)
if (e.Key == System.Windows.Input.Key.Enter && !String.IsNullOrWhiteSpace(((TextBox)sender).Text))
{
e.Handled = true;
isEnterClicked = true;
((System.Windows.Controls.TextBox)sender).Visibility = System.Windows.Visibility.Collapsed;
}
}
After Key.Enter was pressed, TextBox.Visibility is changed, and this operator will raise LostFocus event.
public void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
try
{
if (!isEnterClicked)
{
DependencyObject dob = (DependencyObject)sender;
while ( !(dob is ItemsControl))
{
dob = VisualTreeHelper.GetParent(dob);
}
dynamic myCmd = dob.GetValue(Control.DataContextProperty);
myCmd.SomeCommand.Execute(((TextBox)sender).GetValue(Control.DataContextProperty));
}
}
finally
{
isEnterClicked = false;
}
}
LostFocus handler firstly watch whether isEnterPressed equals to false, its mean, TextBox lost it focus not because enter was pressed. SomeCommand will delete some item which was bind to TextBox, and it will disappear.
Q: So, how to do the same with Button.Click event?
First of all, BEFORE Button clicked, TextBox lost it focus. The same way is not acceptable. Button.Focusable="False", creating new ControlTemplate or handling Timer.Elapsed event do not satisfy my requirements.
If I understood problem correctly, try to check if button is focused, if so dont perform actions in textbox lostfocus event. If Iam correct button should be focused before textbox lostfocus event raised.
if (!isEnterClicked && !button.Focused)
{
//do stuff
}

Categories