windows calculator in c # that allows entry by keyboard

0

Alright guys, I'm a senior in high school, and as it says in the title I need to help me in the realization of the basic calculator (which I already have functional with the mouse), but now I need to adapt it for that accept me values by keyboard (you know, numbers, operations and the delete button, and that when I hit enter, give me the result) thing with which I have had many problems.

The numbers already enter me, but not the other mentioned, I hope they help me is urgent, I am a rookie and it is the first time I do something like that.

Here is the code so you can check it out, it's all commented, thank you very much in advance.

public partial class Form1 : Form
    {
        bool detectaopreacion = true;
        string operacion;
        double result;
        double numero1;
        double numero2;
        bool punto = true;
        string borrado, point;
        double Signos;
        double memoria;
        bool labelmemory = false

        //Instrucciones para botones numericos
        private void btn0_Click(object sender, EventArgs e)
        {
            if (txtrespuesta.Text == "0")
            {
                return;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "0";
            }
        }
        private void btn1_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "1";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "1";
            }

        }
        private void btn2_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "2";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "2";
            }
        }

        private void btn3_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "3";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "3";
            }
        }

        private void btn4_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "4";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "4";
            }
        }

        private void btn5_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "5";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "5";
            }
        }

        private void btn6_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "6";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "6";
            }
        }

        private void btn7_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "7";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "7";
            }
        }

        private void btn8_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "8";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "8";
            }
        }

        private void btn9_Click(object sender, EventArgs e)
        {
            if (detectaopreacion)
            {
                txtrespuesta.Text = "";
                txtrespuesta.Text = "9";
                detectaopreacion = false;

            }
            else
            {
                txtrespuesta.Text = txtrespuesta.Text + "9";
            }
        }

        //Fin de asignación númerica

            //Botones de operaciones, asignación
            //suma
        private void btnmas_Click(object sender, EventArgs e)
        {
            operacion = "+";
            detectaopreacion = true;
            numero1 = double.Parse(txtrespuesta.Text);
        }

        //resta
        private void btnmenos_Click(object sender, EventArgs e)
        {
            operacion = "-";
            detectaopreacion = true;
            numero1 = double.Parse(txtrespuesta.Text);
        }
        //Multiplicación
        private void button12_Click(object sender, EventArgs e)
        {
            operacion = "*";
            detectaopreacion = true;
            numero1 = double.Parse(txtrespuesta.Text);
        }
        //División
        private void btndividir_Click(object sender, EventArgs e)
        {
            operacion = "/";
            detectaopreacion = true;
            numero1 = double.Parse(txtrespuesta.Text);
        }
        //Raiz Cuadrada
        private void btnraiz_Click(object sender, EventArgs e)
        {
            numero1 = double.Parse(txtrespuesta.Text);
            result = Math.Sqrt(numero1);
            txtrespuesta.Text = result.ToString();
            detectaopreacion = true;
        }
        //Potencia
        private void cuadrado_Click(object sender, EventArgs e)
        {
            numero1 = double.Parse(txtrespuesta.Text);
            result = numero1 * numero1;
            txtrespuesta.Text = result.ToString();
        }
        //Porcentaje
        private void btnporcentaje_Click(object sender, EventArgs e)
        {
            numero1 = double.Parse(txtrespuesta.Text);
            result = ((numero1 * numero2) / 100);
            txtrespuesta.Text = result.ToString();
            detectaopreacion = true;
        }
        //Fin de operaciones

            //Botón de igualdad, y llamado de operaciones
        private void btnigual_Click(object sender, EventArgs e)
        {
            numero2 = double.Parse(txtrespuesta.Text);
            detectaopreacion = true;
            switch (operacion)
            {
                case "+":
                    result = numero1 + numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "-":
                    result = numero1 - numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "*":
                    result = numero1 * numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "/":
                    result = numero1 / numero2;
                    txtrespuesta.Text = result.ToString();
                    break;

            }
        }
        //Boton Igual
        private void btnpunto_Click(object sender, EventArgs e)
        {

            if (punto == true)
            {
                txtrespuesta.Text = txtrespuesta.Text + ".";
                punto = false;
            }
            else
            {
                return;
            }
            detectaopreacion = false;
        }

        //Botón limpiar todo
        private void btnce_Click(object sender, EventArgs e)
        {
            txtrespuesta.Text = "0";
            numero1 = 0;
            numero2 = 0;
            detectaopreacion = true;
            punto = true;
        }
        //Botón limpiar 
        private void btnc_Click(object sender, EventArgs e)
        {
            txtrespuesta.Text = "0";
            detectaopreacion = true;
            numero1 = 0;
            numero2 = 0;
            result = 0;
        }

        //Boton retroceso/eliminado unitario
        private void btnretroceso_Click(object sender, EventArgs e)
        {
            int x = 0;
            int y = 0;
            borrado = txtrespuesta.Text;
            point = txtrespuesta.Text;
            x = borrado.Length - 1;
            y = point.Length - 1;
            point = point.Substring(y, 1);
            borrado = borrado.Substring(0, x);
            txtrespuesta.Text = borrado;
            if (txtrespuesta.Text == "")
            {
                txtrespuesta.Text = "0";
                detectaopreacion = true;
            }
            if (txtrespuesta.Text == "-")
            {
                txtrespuesta.Text = "0";
                detectaopreacion = true;
            }
            if (point == ".")
            {
                punto = true;
            }
        }

        //Boton memory clear(borrar memoria)
        private void btnmc_Click(object sender, EventArgs e)
        {
            memoria = 0;
            labelmemory = false;
        }
        //Boton more memory (Más memoria)
        private void btnmr_Click(object sender, EventArgs e)
        {
            txtrespuesta.Text = memoria.ToString();
        }
        //Boton MS(no me acuerdo de las siglas, zorry :p)
        private void btnms_Click(object sender, EventArgs e)
        {
            memoria = Convert.ToDouble(txtrespuesta.Text);
            labelmemory = true;
        }
        //Boton memoria +
        private void btnmmas_Click(object sender, EventArgs e)
        {
            memoria = memoria + Convert.ToDouble(txtrespuesta.Text);
            labelmemory = true;
        }
        //Boton memoria -
        private void btnmmenos_Click(object sender, EventArgs e)
        {
            memoria = memoria - Convert.ToDouble(txtrespuesta.Text);
            labelmemory = true;
        }
        //Boton +-
        private void btnmasmenos_Click(object sender, EventArgs e)
        {
            Signos = double.Parse(txtrespuesta.Text);
            Signos = Signos - (Signos * 2);
            txtrespuesta.Text = Signos.ToString();
        }

        //evento de validacion para admitir numeros por teclado
        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch(e.KeyChar.ToString())
            {
                case "0":
                    btn0.PerformClick();
                    break;
                case "1":
                    btn1.PerformClick();
                    break;
                case "2":
                    btn2.PerformClick();
                    break;
                case "3":
                    btn3.PerformClick();
                    break;
                case "4":
                    btn4.PerformClick();
                    break;
                case "5":
                    btn5.PerformClick();
                    break;
                case "6":
                    btn6.PerformClick();
                    break;
                case "7":
                    btn7.PerformClick();
                    break;
                case "8":
                    btn8.PerformClick();
                    break;
                case "9":
                    btn9.PerformClick();
                    break;
                case "+":
                    btnmas_Click();

                    break;
                case "-":
                    btnmenos.PerformClick();
                    break;
                case "*":
                    btnmul.PerformClick();
                    break;
                case "/":
                    btndividir.PerformClick();
                    break;
                case "s":
                    cuadrado.PerformClick();
                    break;
                case "Enter":
                    btnigual_Click();
                    break;



            }

        }
        private void btnigual_Click()
        {
            btnigual.PerformClick();
            numero2 = double.Parse(txtrespuesta.Text);
            detectaopreacion = true;
            switch (operacion)
            {
                case "+":
                    result = numero1 + numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "-":
                    result = numero1 - numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "*":
                    result = numero1 * numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
                case "/":
                    result = numero1 / numero2;
                    txtrespuesta.Text = result.ToString();
                    break;
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void fuelEconomiToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void editarToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void cientificaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Hide();
            Form Form2 = new Form2();
            Form2.Show();
        }

        private void btnmas_Click()
        {
            detectaopreacion = true;
            numero2 = double.Parse(txtrespuesta.Text);
        }

    }
}
    
asked by Axwell Duarte 14.02.2018 в 21:48
source

1 answer

1

To capture the click of the point you only have to add to the instruction switch a case with the string "." .

The case of the delete key is more complicated since it does not generate the KeyPress event, to detect it you should capture the KeyDown event.

In any case there are several things that can be improved in your code.

Since the same code can be launched from different events (button clicks, keystrokes, ...) it would be better if you use functionality in separate methods and call these methods from different events. That is, you can create a method that implements the addition functionality and call this method from the Click event of the sum button and from the KeyPress event in case the key pressed is a + .

On the other hand, since the data shown in TextBox is not always the same (sometimes it's the first number, sometimes the second, sometimes the result) you should make the calculation logic independent of what is is showing in the TextBox taking those values in independent variables and showing at every moment the value you want in the control.

In addition there is a lot of repeated code that you could save yourself. For example, in the case of the number buttons, if you set the character associated with the button in the property Tag of this or you take it from the text of the button, you could use a single handler for the event Click of all the buttons .

I've come up and I've done an example of how the code of a calculator could be as you put it.

Here is the code. I hope it helps you.

public partial class Form1 : Form
{
    private string _valorActual = "";
    private double _resultado;
    private char _operacionPendiente;
    private readonly TextBox _display;

    public Form1()
    {
        InitializeComponent();

        _display = new TextBox { Left = 10, Top = 10, Width = 240, ReadOnly = true, TabStop = false };
        Controls.Add(_display);

        EventHandler btnClick = (sender, args) => { TeclaPulsada((char)((Button)sender).Tag); };

        for (int i = 1, btnLeft = 10, btnTop = 190;
            i < 10;
            i++, btnLeft += btnLeft == 110 ? -100 : 50, btnTop -= btnLeft == 10 ? 50 : 0)
        {
            var btn = new Button { Left = btnLeft, Top = btnTop, Width = 40, Height = 40, Text = i.ToString(), Tag = char.Parse(i.ToString()), TabStop = false };
            btn.Click += btnClick;
            Controls.Add(btn);
        }
        var btn0 = new Button { Left = 10, Top = 240, Width = 90, Height = 40, Text = @"0", Tag = '0', TabStop = false };
        btn0.Click += btnClick;
        Controls.Add(btn0);
        var btnDot = new Button { Left = 110, Top = 240, Width = 40, Height = 40, Text = @".", Tag = '.', TabStop = false };
        btnDot.Click += btnClick;
        Controls.Add(btnDot);
        char[] operaciones = { '±', '/', '*', '-', '+' };
        for (var i = 0; i < operaciones.Length; i++)
        {
            var btnOperation = new Button { Left = 160, Top = 40 + 50 * i, Width = 40, Height = 40, Text = operaciones[i].ToString(), Tag = operaciones[i], TabStop = false };
            btnOperation.Click += btnClick;
            Controls.Add(btnOperation);
        }
        var btnRaiz = new Button { Left = 210, Top = 40, Width = 40, Height = 40, Text = @"raíz", Tag = 'r', TabStop = false };
        btnRaiz.Click += btnClick;
        Controls.Add(btnRaiz);
        var btnPorcentaje = new Button { Left = 210, Top = 90, Width = 40, Height = 40, Text = @"%", Tag = '%', TabStop = false };
        btnPorcentaje.Click += btnClick;
        Controls.Add(btnPorcentaje);
        var btnInverso = new Button { Left = 210, Top = 140, Width = 40, Height = 40, Text = @"1/x", Tag = 'i', TabStop = false };
        btnInverso.Click += btnClick;
        Controls.Add(btnInverso);

        var btnEnter = new Button { Left = 210, Top = 190, Width = 40, Height = 90, Text = @"=", Tag = '=', TabStop = false };
        btnEnter.Click += btnClick;
        Controls.Add(btnEnter);
        var btnBack = new Button { Left = 10, Top = 40, Width = 40, Height = 40, Text = @"<--", Tag = '\b', TabStop = false };
        btnBack.Click += btnClick;
        Controls.Add(btnBack);
        var btnCe = new Button { Left = 60, Top = 40, Width = 40, Height = 40, Text = @"CE", Tag = 'e', TabStop = false };
        btnCe.Click += btnClick;
        Controls.Add(btnCe);
        var btnC = new Button { Left = 110, Top = 40, Width = 40, Height = 40, Text = @"C", Tag = 'c', TabStop = false };
        btnC.Click += btnClick;
        Controls.Add(btnC);

        KeyPreview = true;
        KeyPress += (sender, args) => { TeclaPulsada(args.KeyChar); };
        KeyDown += (sender, args) =>
        {
            switch (args.KeyCode)
            {
                case Keys.Delete:
                    TeclaPulsada('e');
                    break;
                case Keys.Escape:
                    TeclaPulsada('c');
                    break;
            }
        };
        Width = 280;
        Height = 350;
    }

    private void TeclaPulsada(char key)
    {
        // Es un número
        if (char.IsDigit(key))
        {
            if (_valorActual.Length >= 25) return;
            _valorActual += key.ToString();
            _display.Text = _valorActual;
            return;
        }


        switch (key)
        {
            // Punto decimal (si ya hay uno no hace nada)
            case '.':
                if (!_valorActual.Contains("."))
                {
                    _valorActual += _valorActual.Length == 0 ? "0." : ".";
                    _display.Text = _valorActual;
                }
                break;
            // Operaciones binarias. Ejecuta la operación pendiente (si la hay)
            // y se establece como pendiente la pulsada
            case '+':
            case '-':
            case '*':
            case '/':
                EjecutarOperacionPendiente();
                _operacionPendiente = key;
                break;
            // Otras operaciones
            // Cambio de signo
            case '±':
            case 's':
            case 'S':
                EjecutarOperacionInmediata('±');
                break;
            // raíz cuadrada
            case 'r':
            case 'R':
                EjecutarOperacionInmediata('r');
                break;
            // inverso (1/x)
            case 'i':
            case 'I':
                EjecutarOperacionInmediata('i');
                break;
            case '%':
                // Es un caso particular: de ejecución inmediata
                // pero utiliza dos variables para el cálculo
                EjecutarPorcentaje();
                break;
            // Igual/Enter (resultado)
            case '=':
            case '\r':
                EjecutarOperacionPendiente();
                break;
            // Retroceso (backspace)
            case '\b':
                if (_valorActual.Length > 0)
                {
                    _valorActual = _valorActual.Remove(_valorActual.Length - 1);
                    _display.Text = _valorActual;
                }
                break;
            // Suprimir/E. Eliminar valor actual
            case 'e':
            case 'E':
                _valorActual = "";
                _display.Text = @"0";
                break;
            // Escape/C. Resetear (reiniciar)
            case 'c':
            case 'C':
                _resultado = 0;
                _valorActual = "";
                _display.Text = @"0";
                break;
        }
    }

    private void EjecutarPorcentaje()
    {
        if (string.IsNullOrEmpty(_display.Text) || _display.Text==@"0")
            return;

        var valor = double.Parse(_display.Text, CultureInfo.InvariantCulture);
        valor = _resultado * valor / 100;
        _valorActual = valor.ToString(CultureInfo.InvariantCulture);
        _display.Text = _valorActual;
    }

    private void EjecutarOperacionPendiente()
    {
        if (_valorActual.Length <= 0) return;

        var valor = double.Parse(_valorActual, CultureInfo.InvariantCulture);
        switch (_operacionPendiente)
        {
            case '+':
                _resultado += valor;
                break;
            case '-':
                _resultado -= valor;
                break;
            case '*':
                _resultado *= valor;
                break;
            case '/':
                _resultado /= valor;
                break;
            default:
                _resultado = valor;
                break;
        }
        _valorActual = "";
        _operacionPendiente = char.MinValue;
        _display.Text = _resultado.ToString(CultureInfo.InvariantCulture);
    }

    private void EjecutarOperacionInmediata(char operacion)
    {
        if (!string.IsNullOrEmpty(_valorActual) && _valorActual != @"0")
        {
            _valorActual = AplicarAValor(operacion, _valorActual);
            _display.Text = _valorActual;
        }
        else
        {
            if (!string.IsNullOrEmpty(_display.Text) && _display.Text != @"0")
            {
                _resultado = AplicarAValor(operacion, _resultado);
                _display.Text = _resultado.ToString(CultureInfo.InvariantCulture);
            }
        }
    }

    private string AplicarAValor(char operacion, string valor)
    {
        switch (operacion)
        {
            case '±':
                return valor.StartsWith("-") ? valor.Substring(1) : $"-{valor}";
            case 'r':
            case 'i':
                var numerico = double.Parse(valor, CultureInfo.InvariantCulture);
                return AplicarAValor(operacion, numerico).ToString(CultureInfo.InvariantCulture);
            default:
                return valor;
        }
    }

    private double AplicarAValor(char operacion, double valor)
    {
        switch (operacion)
        {
            case '±':
                return -valor;
            case 'r':
                return Math.Sqrt(valor);
            case 'i':
                return 1 / valor;
            default:
                return valor;
        }
    }

}

The controls and their properties are created in the constructor. This way you can copy the code in an empty form to see it working.

All events end up calling the event TeclaPulsada , which is where all the logic is launched regardless of the event generated by the user.

As you can see to capture the event of the Delete key, I capture the event KeyDown of the form.

Obviously there is a lack of functionality to implement, such as error control (square roots of negative values, divisions between 0, excessively large numbers, ...) but I think it can help you.

    
answered by 15.02.2018 в 23:01