如何在计算器窗体应用程序中正确使用ProcessCmdKey?

时间:2014-12-25 22:14:42

标签: c# .net winforms

我试图在C#Windows窗体应用程序中构建一个普通的计算器。我希望当我按下任何小键盘时,数字将显示在文本框中,就像在任何标准计算器中一样。

因此,通过研究我可以通过覆盖ProcessCmdKey并将Form的KeyPreview属性更改为true来完成此操作。

问题是:当我完全使用numpad时,计算器工作正常。但是,当我将鼠标单击任意数字按钮组合在一起,然后尝试再次使用小键盘时,数字不会显示在TextBox中。

我有一个用于数字按钮的通用点击方法(它将触发0-9所有按钮点击)

private void number_button_Click(object sender, EventArgs e)
{
    Button button = (Button)sender;
    textBox1.Text = textBox1.Text + "" + button.Text;
}

添加方法(类似于减法,除法,乘法的明智方法)

private void buttonPlusClk_Click(object sender, EventArgs e)
{
    sign = "+";
    operandOne = double.Parse(textBox1.Text);
    textBox1.Text = "";
}

表格

this.KeyPreview = true;

重写的ProcessCmdKey方法

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == (Keys.NumPad0 |
        Keys.NumPad1 |
        Keys.NumPad2 |
        Keys.NumPad3 |
        Keys.NumPad4 |
        Keys.NumPad5 |
        Keys.NumPad6 |
        Keys.NumPad7 |
        Keys.NumPad8 |
        Keys.NumPad9))
    {

        // also not sure about the KeyEventArgs(keyData)... is it ok?
        number_button_Click(keyData, new KeyEventArgs(keyData));
        return true;

    }
    else if(keyData == (Keys.Add))
    {
        buttonPlusClk_Click(keyData, new KeyEventArgs(keyData));
        return true;
    }
    // ... and the if conditions for other operators
    return base.ProcessCmdKey(ref msg, keyData);
}

询问我是否要查看任何其他代码。


为了将来参考,请从SSCCE获取GitHub,然后重新创建问题

  1. 按键盘小键盘中的2
  2. 点击+
  3. 按键盘小键盘中的1(您不会看到1进入文本框)
  4. 点击等于

1 个答案:

答案 0 :(得分:1)

在您的密钥处理功能中尝试此操作。当XOR'ing数字不用作旗帜时,它们是不正确的 此外,从此函数调用事件处理程序将导致错误,因为第一个arg不是按钮。

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            int intKey = (int)keyData;
            if (intKey >= 96 && intKey <= 105) // 96 = 0, 97 = 1, ..., 105 = 9
            {
                textBox1.Text = textBox1.Text + (intKey - 96).ToString();
                return true;

            }
            // ... and the if conditions for other operators
            return base.ProcessCmdKey(ref msg, keyData);
        }