【问题标题】:Enter Key press creating extra "1"Enter 按键创建额外的“1”
【发布时间】:2017-10-06 19:07:38
【问题描述】:

我目前正在尝试编写一个简单的 Winforms 计算器,并且正在努力将 NumPad 键分配给表单按钮。到目前为止,我分配的每个按钮都可以正常工作,但 Enter 按钮除外。无论输入的表达式是什么,当按下物理回车键时,它都会在答案here 的末尾添加一个单独的“1”。只需按下表单按钮,它就可以正常工作。 有人知道这是为什么,或者可以帮助我吗? 我也意识到我的一些代码是不需要的,所以放过我吧,我只是个学生!

以下是关键检测代码及其引入的相关方法:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == Keys.Enter)
        {
            enterButton.PerformClick();
        }
        if (keyData == Keys.NumPad0)
        {
            button10.PerformClick();
        }
        if (keyData == Keys.NumPad1)
        {
            button1.PerformClick();
        }
        if (keyData == Keys.NumPad2)
        {
            button2.PerformClick();
        }
        if (keyData == Keys.NumPad3)
        {
            button3.PerformClick();
        }
        if (keyData == Keys.NumPad4)
        {
            button4.PerformClick();
        }
        if (keyData == Keys.NumPad5)
        {
            button5.PerformClick();
        }
        if (keyData == Keys.NumPad6)
        {
            button6.PerformClick();
        }
        if (keyData == Keys.NumPad7)
        {
            button7.PerformClick();
        }
        if (keyData == Keys.NumPad8)
        {
            button8.PerformClick();
        }
        if (keyData == Keys.NumPad9)
        {
            button9.PerformClick();
        }
        if (keyData == Keys.Add)
        {
            addButton.PerformClick();
        }
        if (keyData == Keys.Subtract)
        {
            minusButton.PerformClick();
        }
        if (keyData == Keys.Multiply)
        {
            timesButton.PerformClick();
        }
        if (keyData == Keys.Divide)
        {
            divideButton.PerformClick();
        }
    }
    private void enterButton_Click(object sender, EventArgs e)
    {
        operIsDone = true; //triggers final calculation
        MainCalc();
    }
    private void MainCalc()
    {
        do
        {
            if (operation == '+')
            {
                operand = stringToInt(inputString);
                inputString = cleared;
                ansCache += operand;
                operand = 0;
                break;
            }
            if (operation == '-')
            {
                if (minusButton.Tag.Equals("1"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    ansCache += operand;
                    minusButton.Tag = "2";
                    break;
                }
                else if (minusButton.Tag.Equals("2"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    ansCache -= operand;
                    break;
                }
            }
            if(operation == '*')
            {
                if (timesButton.Tag.Equals("1"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    ansCache += operand;
                    timesButton.Tag = "2";
                    break;
                }
                else if (timesButton.Tag.Equals("2"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    ansCache *= operand;
                    break;
                }
            }
            if(operation == '/')
            {
                if (divideButton.Tag.Equals("1"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    ansCache += operand;
                    divideButton.Tag = "2";
                    break;
                }
                else if (divideButton.Tag.Equals("2"))
                {
                    operand = stringToInt(inputString);
                    inputString = cleared;
                    if (operand != 0)
                    {
                        ansCache /= operand;
                    }
                    else
                    {
                        statusLabel.Text = "Cannot Divide By Zero!";
                    }
                    break;
                }
            }
            else if(operIsDone) { break; }
        }
        while (calc);

        if (operIsDone)
        {
            statusLabel.Text = Convert.ToString(ansCache) + "";
            statusText = statusLabel.Text;
        }

【问题讨论】:

  • 你能上传整个 ProcessCmdKey 我感觉里面发生了什么事。或指向您的 git 存储库的链接,此代码所在的位置
  • 我有根据的猜测是 1 的按钮被设置为表单的 AcceptButton,这可能导致事件被触发两次。
  • 我会尝试将 System.Diagnostics.Debug.WriteLine 添加到 main calc 的开头,我会怀疑 1 键被设置为 else 语句或导致它调用的那种性质的东西maincalc 也是如此
  • ProcessCmdKey 似乎仍然不完整。
  • 抱歉,-1 来自处理网络应用程序,其中 -1 表示控件已脱离表单的 Tab 键顺序。所以,看看我的回答。基本上,您的 Enter 键被处理为 cmd 键单击任何具有焦点的按钮。这是回车键的典型行为。

标签: c# winforms calculator


【解决方案1】:

我的猜测是你的“1”按钮有焦点。当您的计算完成后,回车键会被视为对 1 的点击。回车键被解释为对具有焦点的按钮的点击是标准行为。尝试将“1”按钮的标签索引设置为 0。它应该开始在答案末尾添加“2”。

如果是这种情况,我会做的是在 ProcessCmdKey 中,我对回车键所做的唯一事情就是将焦点转移到计算器的“回车”按钮。

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Enter)
    {
        enterButton.Focus();
    }

键盘 enter 键的常规行为将负责点击该键,因此您不必执行 PerformClick。

并且,将您的输入按钮设置为表单上的“接受”按钮。这意味着每当用户在他们的键盘上按下“Enter”,你的“Enter”按钮的点击事件就会被触发。基本上,按下用户物理键盘上的“Enter”按钮就像点击计算器的“Enter”按钮一样。

基本上,我认为您的问题是您按下 Enter 按钮(在计算答案之后)也被视为按下任何具有焦点的按钮,这会导致“1”按钮的单击事件处理程序也被执行,它调用 button1.PerformClick(),并且“1”被添加到计算器的“显示屏幕”中。

【讨论】:

  • 啊,好主意。我会更进一步说处理 enter 命令可能更容易,然后在 processCmdKey 上返回 false 以完全忽略它,因为焦点可能会导致意外结果。
  • @willthiswork89 - 是的,你是对的。我也不完全喜欢我的答案,并且不知道他的其余代码,很难想出一些东西,但我想我做到了 - 使用表单的“AcceptButton”行为 - 设置“Enter”按钮他的表单是“AcceptButton”,而不是用它作为命令键做任何事情。我已经相应地编辑了我的答案。
  • @agapwlesu 谢谢!这似乎是导致问题的原因。那么我是否只需将焦点设置在输入按钮上,然后再执行 PerformClick() 操作?
  • 不行,取出ProcessCmdKey中处理进入按钮的代码。所以它永远不会作为命令键处理。然后转到表单的属性并将 AcceptButton 设置为计算器的“Enter”按钮。
  • @AgapwIesu 好的,与其他答案结合使用效果很好,但这并不理想,因为我想使用 tab 来访问所有按钮。当 AcceptButton 设置为计算器的 enterButton 并且所有 TabStop 属性设置为 true 时,它​​只会发送当时具有焦点的任何按钮。编辑:正是您在下面第二个答案中提到的内容。
【解决方案2】:

就像 Agapwlesu 提到的那样,这可能是因为您的数字 1 按钮已聚焦,并且 Enter 正在按下 1 按钮以及执行您想要的功能。然而,我的解决方案有点不同。

在每个按钮的属性下,您应该找到一个标记为Tab Stop 的按钮。如果您将每个按钮设置为等于false,它们将不再能够被聚焦,因此当您按下回车键时应防止它们被按下。

【讨论】:

  • 我不喜欢这样,因为它仍然让输入行为根据重点来执行谁知道什么。最好将输入行为更改为单击计算器的“输入”按钮,方法是将其设置为表单的接受按钮。
  • 这适用于我现在的目的,我只是想对其进行编程以查看它是如何工作的,所以感谢大家的帮助。我刚刚设置了一个 GitHub 帐户,在这里查看:github.com/jpdixon1/FullCalcProgram
  • 绝对同意你对 Agapwlesu 的看法。这不是一个完美的解决方案,但值得一试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2012-11-28
  • 2021-08-25
  • 2019-05-10
  • 2020-06-01
  • 2012-01-06
  • 1970-01-01
相关资源
最近更新 更多