How to check the box dynamically without firing check changed function? I have 20 checkboxes that are dynamically created and I have a drop-down that determines how many checkboxes are to be checked.
If I selected 3 and click on 6th check box, that should check checkboxes 9, 7 and 8. In this process I don't want to fire checkchanged function.
CheckBox cb1 = (CheckBox)sender;
selectedbox = int.Parse(cb1.Name);
for (int i = 1; i < selectedquantity; i++)
{
premiumticket[selectedbox].Checked = true;
//here check changed firing i dont want that
selectedbox++;
}
You can't stop CheckBox from firing event when it's state changed. Consider to either unsubscribe from event when you don't need it:
for (int i = 0; i < selectedquantity; i++)
{
premiumticket[selectedbox + i].CheckedChanged -= checkBox_CheckedChanged;
premiumticket[selectedbox + i].Checked = true;
premiumticket[selectedbox + i].CheckedChanged += checkBox_CheckedChanged;
}
or use some flag to omit handling of event if you don't need it:
flag = false;
for (int i = 0; i < selectedquantity; i++)
premiumticket[selectedbox + i].Checked = true;
flag = true;
And in handler:
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
if (!flag)
return;
//...
}
I can't see really solution how not to fire the event. You could disable the event with -= and then add it again with +=.
checkBox.CheckedChanged -= checkBox_CheckedChanged;
checkBox.Checked = true;
checkBox.CheckedChanged += checkBox_CheckedChanged;
The big disadvantag of this is that you would have to fire the event manually if you would like to have this event once, when you're updating the values.
I'd rather set a flag in the class and check this flag in the update code.
Remove the event attached then attach it after the you change the check :
{
cb1.CheckedChanged -= new EventHandler(cb1_CheckedChanged);
premiumticket[selectedbox].Checked = true;
cb1.CheckedChanged += new EventHandler(cb1_CheckedChanged);
}
private void cb1_CheckedChanged(object sender, EventArgs e)
{
// Some COde
}
Re-subscribing (unsubscribing/subscribing) technique is not very nice, because you have to deal with every event handler, making it common, adding flags, etc.
What is really simple to do is to use another event - Click - to simply check changes to the control which are made by user:
private void checkBox1_Click(object sender, EventArgs e)
{
checkBox2.Checked = checkBox1.Checked;
checkBox3.Checked = false;
}
private void checkBox2_Click(object sender, EventArgs e)
{
// this is not called when you set "Checked" programmatically
}
It is obvious, what you have to implement different pattern, to actually do something with data (save them or react on changes), if they are changed programmatically. In above example, clicking checkBox2 will run handler, where you, to example, save something into configuration, while setting checkBox2.Checked = true, when clicking checkBox1, will not.
It may happens, what for some CheckBox'es you will use only Click, for others - only CheckedChanged.
Related
I have a simple WPF application that uses a "frame" for multi-page navigation. One of that pages creates a series of CheckBoxes and adds a couple of handlers (Checked/Unchecked) for each checkbox created. The CheckBoxes work as intended and are programmatically accessible, they can be checked or unchecked by click but none of the two events is ever fired if I click.
Here is the creation of the CheckBoxes:
ModuleStackpanels[i].Children.Add(ModuleCheckBoxes[i]);
StackPanel.SetZIndex(ModuleCheckBoxes[i], 2);
ModuleCheckBoxes[i].Checked += new RoutedEventHandler(ModuleCheckBoxClick);
ModuleCheckBoxes[i].Unchecked += new RoutedEventHandler(ModuleCheckBoxClick);
Where I go from 0 to 30. Then I have the handler:
private void ModuleCheckBoxClick(object sender, RoutedEventArgs e)
{
int CheckBoxCounter = 0;
for(int i=0;i<30;i++)
{
if (ModuleCheckBoxes[i].IsChecked == true) CheckBoxCounter++;
}
if(CheckBoxCounter > 1)
{
Button_QueryStatus.IsEnabled = false;
}
}
But nothing is fired.
Someone has got an idea?
Try to use CheckedChanged instead of Checked and Unchecked.
For example:
public bool checkedthecheckbox { get; set; }
CheckBox testchbox = new CheckBox();
private void Form1_Load(object sender, EventArgs e)
{
testchbox.CheckedChanged += new EventHandler(testchbox_CheckedChanged);
}
void testchbox_CheckedChanged(object sender, EventArgs e)
{
if (testchbox.Checked)
checkedthecheckbox = true;
else
checkedthecheckbox = false;
}
In your case:
ModuleStackpanels[i].Children.Add(ModuleCheckBoxes[i]);
StackPanel.SetZIndex(ModuleCheckBoxes[i], 2);
ModuleCheckBoxes[i].CheckedChanged += new EventHandler(ModuleCheckBoxClick);
private void ModuleCheckBoxClick(object sender, RoutedEventArgs e)
{
int CheckBoxCounter = 0;
for(int i=0;i<30;i++)
{
if (ModuleCheckBoxes[i].IsChecked == true) CheckBoxCounter++;
}
if(CheckBoxCounter > 1)
{
Button_QueryStatus.IsEnabled = false;
}
}
Good news! Not all the checkboxes had the event handler because of a fault in the creation of the buttons. 3 on 30 had it, and these buttons represented a different kind of item.
I just dealt with a similar issue on a WPF app that I did not write the front end for and here it came down to: Checked and similar event handlers will fire if the checkbox is triggered manually or programmatically. Other types are not guaranteed in the same way if you are changing the checkbox by setting to IsChecked.
ex. in my case, they attempted to use a Clicked event handler which would only fire from actual user interaction and not programmatic change, which makes perfect sense because setting the IsChecked status is truly not a click event (even though both can potentially check or uncheck the checkbox)
I am trying to make a trading game and I am trying to add a function that if you buy more than 10 items the buy button does not work anymore. I have started with an if statement
int limit = 10;
int quantity = int.Parse(textBox13.Text);
//Quantity 1
if (quantity >= limit)
{
MessageBox.Show("You have gone beyond the limit!");
}
I am just unsure what the code is that I should use. I have tried making the button invisible if you cant afford this however I would like to try this function.
YourButtonIdHere.Enabled = false;
By setting ButtonID enable to False for disable the button.
Syntax: .Enabled = ;
Example: btnID.Enabled = false;
you can simply disable your button
button1.Enabled = false; // For Disable
button1.Enabled = true; // For Enable
if it does not match with your criteria you can also only disable button's click event
button1.Click -= button1_Click; // For Disable
button1.Click += button1_Click; // For Enable
You can also do it when the text is being entered. Advantage of doing this is that you button will be enabled and disabled while entering text and you won't have to create new event for it. Hope it helps.
private void textBox13_TextChanged(object sender, EventArgs e)
{
try
{
if(Int.TryParse(textBox13.Text) > limit)
{
button1.Enabled=false;
}
else
{button1.Enabled=true;
}
}
catch
{
button1.Enabled=true;
}
}
So, basically I'm using a ComboBox.SelectedIndexChanged event to fill 5 more ComboBoxs wich each have their own SelectedIndexChanged event as well.
The problem is that when the first SelectedIndexChanged event fires to fill the rest.. it also fires the other ComboBoxes' SelectedIndexChanged event.
In order to prevent that, I have found a solution using the event SelectionChangeCommited on the rest of the ComboBoxes.
But now, that event (unlike SelectedIndexChanged) doesn't fire on the first click on the item of the ComboBox... you need to select the item two or three times before it does.
So, my question is: is there any way to fix these problems?
In code, before you 'fill' the secondary comboboxes, unsubscribe from their SelectedIndexChanged event, then re-subscribe when the 'fill' code has run
I would make local variable and set it for the time the SelectedIndexChanged should be ignored
protected bool ignoreSelectedIndexChanged = false;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ignoreSelectedIndexChanged) { return; }
//rest of code
}
it seems to me more explicit than fiddling with the events.
In the main ComboBox use something like:
private void comboBoxMain_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
ignoreSelectedIndexChanged = true;
//comboBox1.SelectedIndex = 1;
//comboBox2.SelectedIndex = 2;
//comboBox3.SelectedIndex = 3;
//...
}
finally
{
ignoreSelectedIndexChanged = false;
}
}
SelectionChangedCommited may be another way how to do it. But it is fired only when user does the selection, what may be limiting for some cases. And there were dome bugs of not firing when it should. I personally avoid it.
Using a flag, for example
in case you only have 2 combo boxes
int flag =0;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch(flag)
{
case 0:
flag = 1;
break;
case 1:
// your code here
// after it you should set flag = 0
break;
default:
break;
}
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
switch(flag)
{
case 0:
flag = 2;
break;
case 2:
// your code here
// after it you should set flag = 0
break;
default:
break;
}
}
and just like that depending on the number of comboboxes you're using.
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;
}
}
In my project, There are two radioButtons. To which I have given same CheckedChanged event by doing
something like this:
DoctorRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
PatientRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
I kept both the RadioButtons in a Panel to make them one true while other one is false.
Now the problem is that I am implementing a very big code in the RadioButton_CheckedChanged event.
Whenever the user is changing the state of any of the two RadioButtons, the event is raising two times.
After so many hours I got the answer, the event is raising two times because both the RadioButton states are being changed(Hence, the event will be raised two times). To solve this problem I am trying to unhook the event temporarily something like this:
RadioButton_CheckedChanged Event: (Not Working)
if (DoctorRadioButton.Checked)
{
PatientRadioButton.CheckedChanged -= RadioButton_CheckedChanged; //Un
//
//My functions
//
PatientRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
}
else
{
DoctorRadioButton.CheckedChanged -= RadioButton_CheckedChanged;
//
//My functions
//
DoctorRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
}
Eventhough the event is executing two times. I know I am doing something wrong in Hooking and Unhooking. Please Help.
You can check the sender RadioButton and place your code accordingly like this -
void RadioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton senderRadioButton = sender as RadioButton;
if (senderRadioButton.Equals(DoctorRadioButton))
// OR senderRadioButton.Name == "DoctorRadioButton"
{
// Place your code here for DoctorRadioButton.
}
else
{
// Place your code here for PatientRadioButton.
}
}
Update
If you can't use two different handlers for both radioButtons and want to execute code only in case checkbox is checked you can do this -
void RadioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton senderRadioButton = sender as RadioButton;
if (senderRadioButton.IsChecked)
{
// Place your code here for check event.
}
}
For an extremely simple (albeit crude) solution would be to not hook both the radio buttons, and hook only one of them to the handler: since checking one radio unchecks the other one, it would work as intended.
A more complicated way would be to use a backing property, like this:
class myForm
{
private bool radioStatus = false; // depends on the default status of the radios
private bool RadioStatus
{
get{return radioStatus;} set {radioStatus = value; Checked_Changed();}
}
public myForm()
{
// Lambdas as handlers to keep code short.
DoctorRadioButton.CheckedChanged += (s,args)=>
{ if((s as RadioButton).Checked) RadioStatus = true; };
PatientRadioButton.CheckedChanged += (s,args)=>
{ if((s as RadioButton).Checked) RadioStatus = false; };
}
void Checked_Changed()
{
if (RadioStatus) // = true --> DoctorRadioButton was checked
{
//code
}
else // = false --> PatientRadioButton was checked
{
//other code
}
}
}
This approach has the advantage of allowing you to abstract from the UI a bit.
Put both radio buttons in the same panel or groupbox and automatically they will be grouped so that only one can be selected at a time.
Its a late solution but i found there is no correct answer for your question so i am posting it may be it works For You
Create Click Event for both radio button and simple put your code beacuse on every click your radio button got checked and your code executes :):):)
private void DoctorRadioButtons_Click(object sender, EventArgs e)
{
//Your code on Doctor Radio Button
}
private void PatientRadioButton_Click(object sender, EventArgs e)
{
// Your code on Patient Radio Button
}