【问题标题】:radioButton.Checked_Changed event firing too many timesradioButton.Checked_Changed 事件触发太多次
【发布时间】:2013-09-23 14:48:21
【问题描述】:

概述:我有一个带有 3 个单选按钮的 groupBox。我有代码应该在更改选定的单选按钮时发生......例如,一个消息框询问“你确定”只是对每个单选按钮更具体一点。选项是打开、关闭和重新打开。单击关闭并重新打开时会弹出消息框,询问您确定要关闭并确定要重新打开。

问题:它当前的工作方式每次更改都会弹出两次消息,因为它正在为选中的事件注册已更改的事件 = true 并再次在选中的 = false 为曾经被选中的那个。

我认为有更好的方法可以做到这一点,但我不确定从 groupBox 使用哪个事件,因此只有一个更改事件而不是 2 个。这是我正在使用的代码示例

private void statusChanged()
{
    DialogResult choice;
    if (formLoading == false)
    {
        btnSave.Enabled = true;
        if (optStatusOpen.Checked == true)
        {
            optStatusOpen.Text = "Opened";
            optStatusClosed.Text = "Close";
            optStatusReOpened.Text = "Re-Open";
            optStatusClosed.Checked = false;
            optStatusClosed.Enabled = true;
            optStatusReOpened.Checked = false;
            optStatusReOpened.Enabled = false;
        }
        else if (optStatusClosed.Checked == true)
        {
            choice = MessageBox.Show("You've selected to close claim: " + txtCaimNumber.Text.ToUpper() + ". Continue?",
                                     "Close Claim Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (choice == DialogResult.Yes)
            {
                if (closeClaim(txtClaimNumber.Text.ToUpper()) == true)
                {
                    MessageBox.Show("Claim successfully closed");
                    txtClaimNumber.Enabled = true;
                    optStatusClosed.Text = "Closed";
                    optStatusOpen.Text = "Open";
                    optStatusOpen.Checked = false;
                    optStatusOpen.Enabled = false;
                    optStatusReOpened.Text = "Re-Open";
                    optStatusReOpened.Checked = false;
                    optStatusReOpened.Enabled = true;
                    dtpCloseDate.Enabled = true;
                    txtClaimNumber.Focus();
                }
            }
            else//choice == no
            {
                formLoading = true;
                if (curStatus == 0) //open
                {
                    optStatusOpen.Checked = true;
                    optStatusClosed.Checked = false;
                    optStatusReOpened.Checked = false;
                }
                else if (curStatus == 2)//reopened
                {
                    optStatusOpen.Checked = false;
                    optStatusClosed.Checked = false;
                    optStatusReOpened.Checked = true;
                    dtpReopenDate.Enabled = true;
                }
                else // curStatus = 1 
                {
                    optStatusOpen.Checked = false;
                    optStatusClosed.Checked = true;
                    optStatusReOpened.Checked = false;
                }
            }
        }
        else //ReOpened.checked = true
        {
            curStatus = 3;
            choice = MessageBox.Show("You've selected to reopen claim: " + txtClaimNumber.Text.ToUpper() + ". Continue?",
                                     "Close Claim Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (choice == DialogResult.Yes)
            {
                if (reOpenClaim(txtClaimNumber.Text.ToUpper()) == true)
                {
                    MessageBox.Show("Claim successfully ReOpened");
                    txtClaimNumber.Enabled = true;
                    optStatusOpen.Text = "Open";
                    optStatusReOpened.Text = "Re-Opened";
                    optStatusClosed.Text = "Close";
                    optStatusClosed.Enabled = true;
                    optStatusOpen.Checked = false;
                    optStatusOpen.Enabled = false;
                    txtClaimNumber.Focus();
                    dtpReopenDate.Enabled = true;
                    dtpReopenDate.Checked = true;                        
                }
            }
            else//choice == no
            {
                formLoading = true;
                optStatusOpen.Checked = false;
                optStatusClosed.Checked = true;
                optStatusReOpened.Checked = false;
            }
        }
    }
}

此方法位于每个单选按钮的 Checked_Changed 事件中,如下所示:

private void optStatusClosed_CheckedChanged(object sender, EventArgs e)
{
    if ((sender as RadioButton).Checked == true) //added this line to solve the problem
        statusChanged();
}

【问题讨论】:

  • 你可以试试这个:if(!((RadioButton)sender).IsChecked) return;
  • 全局变量似乎是您问题的最佳解决方案。无法判断给定的选择是由用户执行的还是由您的代码执行的,因此每次您通过代码执行选择时都会触发相应的事件。通常我依赖一个布尔标志,但就这里你一起执行各种“检查”而言,我猜一个整数会做得更好(例如,在检查两个按钮之前,timesToWait = 2)。我正在写一个答案,但显然你找到了你要找的东西(我猜在这条线上,因为看不到任何其他方式)。
  • 我已阅读您的上次编辑,但我不确定这是否解决了您的问题(在两种情况下您都必须调用该方法按钮是否被选中,不是吗?)。

标签: c# events radio-button groupbox


【解决方案1】:

如果您希望仅针对当前选中的单选按钮调用 statusChanged(),您可以在处理程序中检查单选按钮的 IsChecked 属性 -

private void optStatusClosed_CheckedChanged(object sender, EventArgs e)
{
    if((sender as RadioButton).Checked)
    {
       statusChanged();
    }
}

【讨论】:

  • 如果我看起来有点新手,请原谅我,但我是否正确地假设 if 语句只允许访问 statusChanged() 方法,当它被检查 == true 不检查 == false 时?
  • 所以我尝试了你的解决方案,尽管 .Checked == true 选项可用,但 .IsChecked 不可用。我正在检查这个作为答案,因为您帮助我找到了我正在寻找的东西。我正在编辑我的问题以反映正确的答案。
  • 我已经编辑了答案,是的,.Checked 就足够了。相当于.Checked==true
  • 我不确定我是否错过了什么,但恐怕这不是 OP 正在寻找的解决方案:他希望每次单击按钮时调用 statusChanged 方法(选中或不是)。他不想在选择由代码执行时调用它,而只是由用户调用。您的解决方案无法解决此问题。
  • @varocarbas - OP 已接受答案。所以,我猜他只想要这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 2015-03-24
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多