【问题标题】:Radio button checked changed event fires twice选中的单选按钮已更改事件触发两次
【发布时间】:2012-07-14 16:23:37
【问题描述】:

请阅读我的问题,它不是重复的。

我在 Windows 窗体上有三个单选按钮,所有这些按钮都关联了共同的“CheckedChanged”事件。当我单击这些单选按钮中的任何一个时,它会触发两次“CheckedChanged”事件。

这是我的代码:

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

我插入了断点,并且此事件中的整个代码迭代了两次。 请告诉我为什么会这样?

【问题讨论】:

标签: c# winforms radio-button oncheckedchanged


【解决方案1】:

作为正确的回答者正确地说,事件被解雇两次,因为每当一个组内的一个Radiobutton被检查另一个时,将取消选中 - 因此,被检查的更改的事件将射击两次。

要仅在此事件中为刚刚被选中的 RadioButton 执行任何工作,您可以查看 sender 对象,执行以下操作:

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

【讨论】:

  • 你不觉得'if (rb != null)' 是不必要的吗?
  • @MuhammadAliDildar 它在这里避免了任何空引用异常的机会 - 当然,由于您连接了所有事件,您可以确定这个事件处理程序只会附加到一个单选按钮,但是“最佳实践”的做事方式是检查演员表是否有效。再说一遍 - 从某个角度来看,当您错误地附加事件处理程序时抛出异常可能更可取,这样您就可以修复代码。
【解决方案2】:

为避免这种情况,只需检查radioButton 是否被选中

例如:

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

【讨论】:

    【解决方案3】:

    每当 Checked 属性更改时,就会引发 CheckedChanged。如果您选择一个 RadioButton,那么之前选择的 RadioButton 会被取消选中(触发 CheckedChanged),然后新的 RadioButton 会被选中(触发 CheckedChanged)。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您可以将每个 RadioButton 的 AutoCheck 属性设置为 true,然后捕获 Click 事件而不是 CheckChanged 事件。这将确保仅触发一个事件,并且如果需要处理单击,处理程序中的逻辑可以将发送者转换为 RadioButton 类型。如果处理程序逻辑很简单,通常可以避免强制转换。这是一个处理 rbTextNumeric、rbTextFixed 和 rbTextFromFile 三个控件的示例:

                private void rbText_Click(object sender, EventArgs e)
            {
               flowLayoutPanelTextNumeric.Enabled = rbTextNumeric.Checked;
               txtBoxTextFixed.Enabled = rbTextFixed.Checked;
               flowLayoutPanelTextFromFile.Enabled = rbTextFromFile.Checked;
            }
        

        【讨论】:

        • 这似乎适用于 Windows 窗体,但不适用于 Web 窗体。
        【解决方案6】:
        {
            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";
                    }
                }
        
            }
        }
        

        【讨论】:

        • @davidkonrad real 代码永远不需要任何解释!哇!
        【解决方案7】:

        其他答案是正确的,但错过了潜在问题的原因。 检查单选按钮时,发送的第一个事件是未选中的项目的更改 但是,如果您通过其控件名称检查其状态,您仍将看到其旧的检查状态,因为该表单尚未更新。要查看其真实状态,您需要强制转换发送者对象。 这允许您在需要时执行与正在取消选择的条件相关的任何操作。

        在下面的常见场景中,多个单选按钮被发送到同一个处理程序事件。 简单地检查发件人的状态是否已检查在这里不起作用,因为我们需要根据按下的单选按钮执行不同的操作。 所以首先我们忽略任何刚刚被取消选中的发件人。 然后我们通过控件名称识别被检查的发件人以处理正确的操作。

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

        【讨论】:

          【解决方案8】:

          当有一系列单选按钮连续点击时,会出现这种双重检查问题。我遇到了同样的问题。最后一次点击会给出两个结果。为了克服这个问题,我最后做了一个虚拟点击。双击停止.试试这个方法。 文卡特拉曼

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-02
            • 1970-01-01
            • 2011-12-24
            • 2013-07-19
            • 2016-10-10
            • 2015-09-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多