I have a group box which has some radio buttons. I am trying to implement serialization with the help of a tutorial from Code Project. That tutorial supports serialization of checkboxes and not radio buttons. So i need to make the radio buttons in my app as checkboxes (that is they should be check boxes but work like a radiobutton).
I tried writing code, but what happens is when I find that a particular checkbox is checked and I go to uncheck or vice versa, it triggers that checked_changed event handler and this goes into an infinite loop.
Can someone help me out with this?
Thanks
UPDATE:
After seeing your replies, I would like to say thanks a lot. Yes, You are all right that we should not be messing with the basic properties. I will work with changing the serialization method.
P.S The link for the tutorial is http://www.codeproject.com/KB/dialog/SavingTheStateOfAForm.aspx
Final Update:
After following the replies posted here, I decided not to change the default properties but to change the serializer code. I did that and it now works perfectly. Thanks a lot, everyone.
I agree with all the commenters: do not make checkboxes that act like radio buttons, it flies in the face of UI conventions and confuses users.
The right way to do this is to fix your code to serialize the radio buttons, but without seeing your code it's hard to know how to help you. For a start, you can fix the CheckedChanged looping by temporarily removing the event handler before you do anything. For example:
myCheckBox.CheckedChanged -= MyCheckedChangedEventHandler;
myCheckBox.Checked = true;
myCheckBox.CheckedChanged += MyCheckedChangedEventHandler;
If this alone doesn't fix your issue, please show us your code and we'll try to help more.
Edit: Based on the tutorial listed in your update, I'm guessing the problem happens when you call FormSerialisor.Deserialise(), which triggers your controls' event handlers to fire? If that's the case, the quick fix is to just do what I mentioned: remove the radio button event handlers before calling FormSerialisor.Deserialise() and then re-add them afterwards. Example:
myRadioButton.CheckedChanged -= MyCheckedChangedEventHandler;
FormSerialisor.Deserialise(this, mySerialisepath);
myRadioButton.CheckedChanged += MyCheckedChangedEventHandler;
You may also need to edit the FormSerialisor class to handle RadioButtons; just copy the code that handles checkboxes but change all the references to RadioButton. It's not clear from your question whether this step will be necessary or not.
Like the comments say, you're better of getting serialisation to work with radio buttons than messing around with checkboxes. Having said that, to get the effect you need, just set a variable that indicates you're already handling a change event, and test for it. Something like this (it's terrible code, but demonstrates the idea):
private bool autoChange = false;
private void ChangeHandler() {
if (!autoChange) {
autoChange = true;
/* Do stuff */
autoChange = false;
}
}
Unregister from the Checkedevent (by using -=) before doing that. And re-register after you're done.
(I'm not arguing with the comments. Just answering the question.)
Hello, here a simple ansewer to transform the CheckBox to a RadioButton:
object clickBox = null;
private void checkBox_Click(object sender, EventArgs e)
{
clickBox = sender;
foreach (Control c in this.Controls)
{
if (c is CheckBox)
{
if (c != clickBox)
{
((CheckBox)c).Checked = false;
}
}
}
And add this Click event o every Checkbox
Finish
Take the CheckedListBox and call ItemCheck Event and use below code It will behave like Radio buttons (It works for me):-
private void chkListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Checked)
{
for (int item = 0; item < chkListBox.Items.Count; item++)
{
chkListBox.SetItemChecked(item, false);
}
}
}
Related
I'm trying to force the user to select a rabiobutton before being allowed to move next. I made the "Next" button invisible but I have like 10 radiobuttons that must be verified if any of them are checked. By definition, only 1 radiobutton can be checked. My code looks something like this:
b1.Text = "Next";
b1.Parent = fpn1;
fpn1.Controls.Add(b1);
b1.Dock = DockStyle.Bottom;
b1.BackColor = Color.LightGray;
b1.Visible = false;
RadioButton rb;
while (b1.Visible == false)
{
MessageBox.Show("LOOOL");
//Thread.Sleep(5000);
rb = fpn1.Controls.OfType<RadioButton>()
.FirstOrDefault(r => r.Checked);
if (rb != null)
{
b1.Visible = true;
}
}
So while none of my radiobuttons is clicked, b1 is invisible. The problem is... this going into an infinite loop. The user can't even pick any button anymore cause the page won't load. Any idea of a get-around?
What else can I do to have the wanted result?
Infinite loops are really good at blocking an application from doing anything. Essentially, you're thinking about it backwards. You're thinking:
Keep making the button invisible until something happens.
Why? Once you make the button invisible, it's going to stay that way until you change it. So, instead, think of it this way:
Make the button visible when something happens.
In this case "something happens" is a user changing the values of your radio buttons. So you want a handler for that event:
private void radioButton_CheckedChanged(Object sender, EventArgs e)
{
// your logic here
}
You can use the forms designer to assign this function to all of the CheckedChanged events of the various radio buttons, so they all use the same handler.
Then what would "your logic" be? Well, really, that's up to you. It sounds like you want to wait until several different radio button groupings have been selected? So you'd build some conditional based on that. At a high level, that would semantically look like this:
if (allRadioButtonsSelected())
b1.Visible = true;
If the line of code you have does what you want:
rb = fpn1.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked)
then you could even just use that:
if (fpn1.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked) != null)
b1.Visible = true;
Though it doesn't entirely sound like that's what you're looking for, since that's going to tell you if just one radio button is checked. But I may have misunderstood you on that, so it's up to you.
The point is, don't keep looping and blocking the thread while checking to see if something has happened. Because while you're blocking the thread, it will never happen. Instead, use event handlers to respond to events when they happen.
You are blocking the thread that's why it is not loading. I don't see a reason why you need a loop as when a user clicks a radio button you can raise an event. Then when you handle the event you set the visibility to true.
Basically, I have a list of delivery checkboxes one for deliver to this address and another for deliver to a separate address, I basically want to make it so once one has been checked the other can not be checked out (perhaps by greying it out or something along those lines)
Please be aware that both boxes use the same controls.
Listen to the first CheckBox's CheckedChanged event with a method like this one:
private void checkBox1_checkedChanged(object sender, EventArgs e)
{
this.checkBox2.Enabled = !this.checkBox1.Checked;
// If you want it to be unchecked as well as grayed out,
// then have this code as well:
if (!this.checkBox2.Enabled)
{
this.checkBox2.Checked = false;
}
}
But you should consider using RadioButtons instead of CheckBoxes, if it logically fits to your needs.
Use the following code,
checkboxToBeGreyed.Enabled = false;
You have write this code in other checkbox's checked event . Hope this helps.
Just like many things in WPF, sometimes the easiest things are the ones that are hardest to find examples for! How do you clear out the current text of an AutoCompleteBox? In my OnFocus event I want to make sure that the user is given a clear box for entry. So my event procedure looks like
private void autGlobal_GotFocus(object sender, RoutedEventArgs e)
{
AutoCompleteBox acb = (AutoCompleteBox)sender;
if (acb.SearchText == "Search Term")
{
//clear out the box if it has the focus
this.autGlobal.Text = "";
}
}
However, setting the text property directly does not seem to work. Am I missing something obvious?
You need reset Selected Item too.
private void SearchAutoCompleteBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
SearchAutoCompleteBox.SelectedItem = null;
SearchAutoCompleteBox.Text = string.Empty;
}
Have you tried setting the property on your local variable?
acb.Text = string.Empty;
I have a feeling there may be additional code affecting the .Text field when the focus or textchange events are firing.
I think I found the answer after spending a ton of time on this and the XAML. This code example will not work when the IsTextCompletionEnabled option is set to true in the XAML. I set it to false and this code works fine.
I'm writing an application in C# using Visual Studio 2010. All of a sudden the strangest thing has started happening, though.
I have two radio boxes at the top of the window, both are set to Checked = False. I have searched everywhere in the code, I see no reason why it would be anything but False.
Now, the first of these two boxes (called Radio1 and Radio2 respectively) has started being automatically checked when the application is executed. This causes a problem since there is an event associated with the boxes being checked, and now this event runs every time the program is opened (resulting in some serious issues).
Has anybody got any ideas why this box is automatically being checked? As I mentioned, I have looked everywhere through the code just in case I had a Radio1.Checked = true; dangling somewhere. But that is not the case.
The RadioButton class contains code to ensure that at least one button in the group is checked when one of them gets the focus and the AutoCheck property is set to True. This implements the standard behavior of radio buttons. If you want non-standard behavior then you have to set their AutoCheck properties to false and implement the checking yourself.
Use a counter mechanism so that you can override the click method the first time. like this
form_load
{
counter=0;
}
private void rb1_Click(object sender, EventArgs e)
{
if (counter == 0) { counter++;}
else {
//Do your stuff
}
}
private void rb2_Click(object sender, EventArgs e)
{
if (counter == 0) { counter++;}
else {
//Do your stuff
}
}
Hope this is helpfull.
There should be no reason for this to happen unless you are setting the property within the designer or via code. Strange.
I'm working with a data grid that contains a Combo Box Column, but editing this Combo Box (by simply clicking on it) gets annoying sometimes, since one must click at least twice to change the value of that field. I want to change that behaviour, so I thought it would be very simple: just create a OnMouseOver event to make the mouse-overed combo box be selected, but the only available event is the Disposed one.
Is there any way to change this behaviour?
I just dealt with the same problem, and solved it by setting the DataGridView.EditMode to EditOnEnter.
If you don't like that behaviour for all your other columns, I found this suggestion for placing in the CellEnter event:
if (DataGridView1.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn)
{
((DataGridViewComboBoxEditingControl)DataGridView1.EditingControl).DroppedDown = true;
}
I haven't tried it, but it looks promising. The same technique is discussed on this question.
In Winforms, there's a CellMouseEnter event (and a CellEnter event for non-mouse navigation) on the DataGridView. You can use that to set the selected cell.
The reason you are getting only the Disposed event (I think) is because you are trying to go too deep. I get only the Disposed event when I try to go all the way to dataGridView1.Columns["Column1"]...
Instead, as KeithS mentioned, you can assign the CellMouseEnter event to your DataGridView.
From there, you can do the following...
private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex==0 || e.ColumnIndex==2)
{
dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
dataGridView1.BeginEdit(true);
}
}
That if-statement is just there to show how to restrict this functionality to certain columns, in case you want that.
The first line inside the if-statement sets the current cell and the second line begins the edit process.
This is a general process that should work with any type of column you can throw into a DataGridView. The DataGridView's EditMode shouldn't matter.
This works really good.
On the CellClick event of the datagridview:
void datagridview1_CellClick(object sender, .Windows.Forms.DataGridViewCellEventArgs e){if (e.ColumnIndex > 0)
{
W1.dGVReports.CurrentCell = W1.dGVReports.Rows[e.RowIndex].Cells[e.ColumnIndex];
W1.dGVReports.BeginEdit(true);
(W1.dGVReports.EditingControl as System.Windows.Forms.DataGridViewComboBoxEditingControl).DroppedDown = true;
}
}