简体   繁体   中英

Radio button checked changed event fires twice

Please read my question its not a duplicate one.

I've three radio buttons on windows form and all these buttons have common 'CheckedChanged' event associated. When I click any of these radio buttons, it triggers the 'CheckedChanged' event twice.

Here is my code:

private void radioButtons_CheckedChanged(object sender, EventArgs e)
{
    //My Code
}

I inserted the breakpoint and the whole code within this event iterates twice. Please tell me why it is behaving like this?

As the other answerers rightly say, the event is fired twice because whenever one RadioButton within a group is checked another will be unchecked - therefore the checked changed event will fire twice.

To only do any work within this event for the RadioButton which has just been selected you can look at the sender object, doing something like this:

void radioButtons_CheckedChanged(object sender, EventArgs e)
{
    RadioButton rb = sender as RadioButton;
    if (rb != null)
    {
        if (rb.Checked)
        {
            // Only one radio button will be checked
            Console.WriteLine("Changed: " + rb.Name);
        }
    }
}

CheckedChanged is raised whenever the Checked property changes. If you select a RadioButton then the previously selected RadioButton is unchecked (fired CheckedChanged), and then the new RadioButton is checked (fired CheckedChanged).

To avoid it, just check if radioButton is checked

for example:

private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
    if (radioButton1.Checked)
        //your code
}

它触发一次单选按钮从选中状态转换为未选中状态,并再次触发单选按钮从未选中状态转换为选中状态(即选中状态的任何更改都会触发事件)

You could set the AutoCheck property true for each RadioButton then catch the Click event instead of the CheckChanged event. This would ensure that only one event is fired, and the logic in the handler can cast the sender to type RadioButton if needed to process the click. Often the cast can be avoided if the handler logic is simple. Here is an example which handles three controls, rbTextNumeric, rbTextFixed and rbTextFromFile:

        private void rbText_Click(object sender, EventArgs e)
    {
       flowLayoutPanelTextNumeric.Enabled = rbTextNumeric.Checked;
       txtBoxTextFixed.Enabled = rbTextFixed.Checked;
       flowLayoutPanelTextFromFile.Enabled = rbTextFromFile.Checked;
    }
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();
        }
        int click = 0;
        private void radioButton1_Click(object sender, EventArgs e)
        {
            click++;
            if (click %2==1)
            {
                radioButton1.Checked = true;
            }
            if (click %2==0)
            {
                radioButton1.Checked = false;
            }
            if (radioButton1.Checked==true)
            {
                label1.Text = "Cheked";
            }
            if (radioButton1.Checked==false)
            {
                label1.Text = "Uncheked";
            }
        }

    }
}

The other answers are correct but miss the reason for the underlying problem. When a radio button is checked the first event sent is the change from the unchecked item however if you check its state by its control name you will still see its old checked status because the form has not been updated yet. To see its true status you need to cast the sender object. This allows you to perform any actions relating to the condition which is being deselected should you need to do so.

In the not uncommon scenario below multiple radio buttons are sent to the same handler event. Simply checking the state of the sender for checked will not work here as we need to perform different actions depending on which radio button has been pressed. So first we ignore any sender that has just been unchecked. then we identify the checked sender by control name to process the correct action.

private void ModeChangedExample(object sender, EventArgs e)
{
    // multiple radio buttons come here
    // We only want to process the checked item.
    // if you need to something based on the item which was just unchecked don't use this technique. 
    // The state of the sender has not been updated yet in the form.
    // so checking against rdo_A check state will still show it as checked even if it has just been unchecked
    // only the sender variable is up to date at this point.
        
    // To prevent processing the item which has just been uncheked
    RadioButton RD = sender as RadioButton;
    if (RD.Checked == false) return;

    if (rdo_A.Name == RD.Name)
    {
        //Do stuff
    }

    if (rdo_B..Name == RD.Name)
    {
        // Do other stuff
    }

    if (rdo_C.Name == RD.Name)
    {
        // Do something else
    }

}

This problem of double checking happens when there is a series of RadioButton Clicks in succession.I had this same problem.The last click will give two results.To overcome this i made a dummy click in the end.The double click stopped.Try this method. Venkatraman

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM