c# keyboard input in WPF DataGrid

A A 61 Reputation points
2021-03-19T13:51:37.077+00:00

Hey,

I am doing a simple calculator as an exercise and I am quite new in c#.

How to input keyboard?
maybe I need just numbers and =-+ and ENTER
if its letter I would like it to be "Error"

Code XALM:

<Window x:Class="Calculator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Calculator"
        mc:Ignorable="d"
        Title="MainWindow" Height="500" Width="300">
    <Grid Margin="8">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1.5*"/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Label x:Name="result" Content="0" Grid.ColumnSpan="4" HorizontalAlignment="Right" 
               VerticalAlignment="Bottom" FontSize="50"/>
        <Button Content="AC" Margin="2" Grid.Column="0" Grid.Row="1"
                FontWeight="bold" Click="OperationButton_Click"/>
        <Button Content="+/-" Margin="2" Grid.Column="1" Grid.Row="1"
                FontWeight="bold" Click="OperationButton_Click"/>
        <Button Content="%" Margin="2" Grid.Column="2" Grid.Row="1"
                FontWeight="bold" Click="OperationButton_Click"/>
        <Button Content="÷" Margin="2" Grid.Column="3" Grid.Row="1"
                FontWeight="bold" Click="OperationButton_Click"/>

        <Button Content="7" Margin="2" Grid.Column="0" Grid.Row="2"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="8" Margin="2" Grid.Column="1" Grid.Row="2"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="9" Margin="2" Grid.Column="2" Grid.Row="2"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="×" Margin="2" Grid.Column="3" Grid.Row="2"
                FontWeight="bold" Click="OperationButton_Click"/>

        <Button Content="4" Margin="2" Grid.Column="0" Grid.Row="3"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="5" Margin="2" Grid.Column="1" Grid.Row="3"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="6" Margin="2" Grid.Column="2" Grid.Row="3"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="-" Margin="2" Grid.Column="3" Grid.Row="3"
                FontWeight="bold" Click="OperationButton_Click"/>

        <Button Content="1" Margin="2" Grid.Column="0" Grid.Row="4"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="2" Margin="2" Grid.Column="1" Grid.Row="4"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="3" Margin="2" Grid.Column="2" Grid.Row="4"
                FontSize="20" Click="NumberButton_Click"/>
        <Button Content="+" Margin="2" Grid.Column="3" Grid.Row="4"
                FontWeight="bold" Click="OperationButton_Click"/>

        <Button Content="0" Margin="2" Grid.Column="0" Grid.Row="5" 
                FontSize="20" Grid.ColumnSpan="2" Click="NumberButton_Click"/>
        <Button x:Name="dec" Content="" Margin="2" Grid.Column="2" Grid.Row="5"
                FontWeight="bold" Click="OperationButton_Click"/>
        <Button Content="=" Margin="2" Grid.Column="3" Grid.Row="5"
                FontWeight="bold" Click="OperationButton_Click"/>
    </Grid>
</Window>

code c#:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;

namespace Calculator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        double firstNumber, secondNumber, resultNumber = 0;
        bool calcDone = false;
        Operations operation = Operations.None;
        string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

        public MainWindow()
        {
            InitializeComponent();

            //Assign to the decimal button the separator from the current culture
            dec.Content = separator;
        }

        //List the possible numeric operations
        private enum Operations
        {
            None,
            Division,
            Multiplication,
            Subtraction,
            Sum
        }

        //Manage number buttons input
        private void NumberButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;

            if (calcDone) //calculation already done
            {
                result.Content = $"{button.Content}";
                calcDone = false;
            }
            else //calculation not yet done
            {
                if (result.Content.ToString() == "0")
                {
                    result.Content = $"{button.Content}";
                }
                else
                {
                    result.Content = $"{result.Content}{button.Content}";
                }
            }

        }

        //Manage operation buttons input
        private void OperationButton_Click(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;

            //Evaluate button pressed
            switch (button.Content.ToString())
            {
                case "AC":
                    result.Content = "0";
                    break;
                case "+/-":
                    if (!(result.Content.ToString() == "0"))
                    {
                        result.Content = Convert.ToDouble(result.Content) * -1;
                    }
                    break;
                case "%":
                    if (!(result.Content.ToString() == "0"))
                    {
                        result.Content = Convert.ToDouble(result.Content) / 100;
                    }
                    break;
                case "÷":
                    firstNumber = Convert.ToDouble(result.Content);
                    operation = Operations.Division;
                    result.Content = "0";
                    break;
                case "×":
                    firstNumber = Convert.ToDouble(result.Content);
                    operation = Operations.Multiplication;
                    result.Content = "0";
                    break;
                case "-":
                    firstNumber = Convert.ToDouble(result.Content);
                    operation = Operations.Subtraction;
                    result.Content = "0";
                    break;
                case "+":
                    firstNumber = Convert.ToDouble(result.Content);
                    operation = Operations.Sum;
                    result.Content = "0";
                    break;
                case "=":
                    switch (operation)
                    {
                        case Operations.Division:
                            if (calcDone)
                            {
                                if (!(result.Content.ToString() == "ERROR"))
                                {
                                    result.Content = Convert.ToDouble(result.Content) / secondNumber;
                                }
                            }
                            else
                            {
                                //Check if division by 0
                                if (result.Content.ToString() == "0")
                                {
                                    result.Content = "ERROR";
                                    calcDone = true;
                                }
                                else
                                {
                                    secondNumber = Convert.ToDouble(result.Content);
                                    resultNumber = firstNumber / secondNumber;
                                    result.Content = resultNumber;
                                    calcDone = true;
                                }
                            }
                            break;
                        case Operations.Multiplication:
                            if (calcDone)
                            {
                                result.Content = Convert.ToDouble(result.Content) * secondNumber;
                            }
                            else
                            {
                                secondNumber = Convert.ToDouble(result.Content);
                                resultNumber = firstNumber * secondNumber;
                                result.Content = resultNumber;
                                calcDone = true;
                            }
                            break;
                        case Operations.Subtraction:
                            if (calcDone)
                            {
                                result.Content = Convert.ToDouble(result.Content) - secondNumber;
                            }
                            else
                            {
                                secondNumber = Convert.ToDouble(result.Content);
                                resultNumber = firstNumber - secondNumber;
                                result.Content = resultNumber;
                                calcDone = true;
                            }
                            break;
                        case Operations.Sum:
                            if (calcDone)
                            {
                                result.Content = Convert.ToDouble(result.Content) + secondNumber;
                            }
                            else
                            {
                                secondNumber = Convert.ToDouble(result.Content);
                                MessageBox.Show($"{firstNumber} + {secondNumber}");
                                resultNumber = firstNumber + secondNumber;
                                result.Content = resultNumber;
                                calcDone = true;
                            }
                            break;
                    }
                    break;
                default:
                    if (!result.Content.ToString().Contains(separator))
                    {
                        result.Content = $"{result.Content}{button.Content}";
                    }
                    break;
            }
        }
    }
}

So what should I do?

Thanks!

Best regards,
AA

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,663 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,175 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Sam of Simple Samples 5,516 Reputation points
    2021-03-19T20:13:02.697+00:00

    It is not clear to me what you mean by input keyboard. There are two possible meanings.

    You can choose one character within the Content attribute to be used as the AccessKey, as described in #838 – Using a Label’s Access Key to Give Focus to Another Control. So in other words if you change (for the relevant button) Content="1" to Content="_1" then when the "1" key is pressed then that will work the exact same way as if the "1" button is pressed.

    If you do that then you normally would have a separate event handler for each button. For your form here you have NumberButton_Click as the event handler for every number. You could create a separate event handler for each number but if you want you can modify NumberButton_Click so that it can determine which number was pressed, as in the following:

    private void NumberButton_Click(object sender, RoutedEventArgs e)  
    {  
        Button button = (Button)sender;  
    
        string s = button.Content.ToString();  
        if (s.Length != 2)  
            {  
                System.Diagnostics.Debug.WriteLine($"NumberButton content is not valid");  
                return;  
            }  
    
        if (calcDone) //calculation already done  
        {  
            result.Content = s[1];  
            calcDone = false;  
        }  
        else //calculation not yet done  
        {  
            if (result.Content.ToString() == "0")  
            {  
                result.Content = s[1];  
            }  
            else  
            {  
                result.Content = result.Content.ToString() + s[1];  
            }  
        }  
    
    }  
    

    That is if the Content is in the format "_n" where n is a number. You can use the similar code for OperationButton_Click. For the AC button you need to choose one character, either A or C, to be used as the access key. I am not sure what the "+/-" button is for but you will need to choose one character to be used as the access key for it. If it is for toggling the number between positive and negative then I am not sure what to do; the Windows Calculator accessory has such a button and as best as I can tell it cannot be used from the keyboard.

    Another possibility requires the understanding of focus. Unless a key is specified for use as an accelerator or (as in the preceding) an access key, Windows normally sends keyboard input to the control with focus. So you need a text box that has the focus to get keyboard input. I am sure there have been times when you type something into an application and nothing happens until you click something like a text box. When you do you are setting the text box as the control with the focus. You might not need to use a text box for that if everything can be done using access keys but note that the Windows Calculator accessory has such a text box.


  2. DaisyTian-1203 11,616 Reputation points
    2021-03-23T02:59:58.117+00:00

    I update your Xaml like below to implement what you want:

    <Window x:Class="Calculator.MainWindow"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:Calculator"  
            mc:Ignorable="d"  
            Title="MainWindow" Height="450" Width="800" PreviewKeyDown="Window_KeyDownPreview">  
        <Grid Margin="8">  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition/>  
                <ColumnDefinition/>  
                <ColumnDefinition/>  
                <ColumnDefinition/>  
            </Grid.ColumnDefinitions>  
            <Grid.RowDefinitions>  
                <RowDefinition Height="1.5*"/>  
                <RowDefinition/>  
                <RowDefinition/>  
                <RowDefinition/>  
                <RowDefinition/>  
                <RowDefinition/>  
            </Grid.RowDefinitions>  
            <Label x:Name="result" Content="0" Grid.ColumnSpan="4" HorizontalAlignment="Right"   VerticalAlignment="Bottom" FontSize="50"/>  
            <Button x:Name="Clear" Content="AC" Margin="2" Grid.Column="0" Grid.Row="1" FontWeight="bold" Click="OperationButton_Click"/>  
            <Button x:Name="Plus_Minus" Content="+/-" Margin="2" Grid.Column="1" Grid.Row="1" FontWeight="bold" Click="OperationButton_Click"/>  
            <Button x:Name="Percent" Content="%" Margin="2" Grid.Column="2" Grid.Row="1" FontWeight="bold" Click="OperationButton_Click"/>  
            <Button x:Name="Divide" Content="÷" Margin="2" Grid.Column="3" Grid.Row="1" FontWeight="bold" Click="OperationButton_Click"/>  
                      
            <Button x:Name="Seven" Content="7" Margin="2" Grid.Column="0" Grid.Row="2" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Eight" Content="8" Margin="2" Grid.Column="1" Grid.Row="2" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Nine" Content="9" Margin="2" Grid.Column="2" Grid.Row="2" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Multiply" Content="×" Margin="2" Grid.Column="3" Grid.Row="2" FontWeight="bold" Click="OperationButton_Click"/>  
                       
            <Button x:Name="Four" Content="4" Margin="2" Grid.Column="0" Grid.Row="3" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Five" Content="5" Margin="2" Grid.Column="1" Grid.Row="3" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Six" Content="6" Margin="2" Grid.Column="2" Grid.Row="3" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Minus" Content="-" Margin="2" Grid.Column="3" Grid.Row="3" FontWeight="bold" Click="OperationButton_Click"/>  
      
            <Button x:Name="One"  Content="1" Margin="2" Grid.Column="0" Grid.Row="4" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Two" Content="2" Margin="2" Grid.Column="1" Grid.Row="4" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Three" Content="3" Margin="2" Grid.Column="2" Grid.Row="4" FontSize="20" Click="NumberButton_Click"/>  
            <Button x:Name="Plus" Content="+" Margin="2" Grid.Column="3" Grid.Row="4" FontWeight="bold" Click="OperationButton_Click"/>  
      
            <Button x:Name="Zero" Content="0" Margin="2" Grid.Column="0" Grid.Row="5" FontSize="20" Grid.ColumnSpan="2" Click="NumberButton_Click"/>  
            <Button x:Name="dec" Content="" Margin="2" Grid.Column="2" Grid.Row="5" FontWeight="bold" Click="OperationButton_Click"/>  
            <Button x:Name="Equals" Content="=" Margin="2" Grid.Column="3" Grid.Row="5" FontWeight="bold" Click="OperationButton_Click"/>  
        </Grid>  
    </Window>  
      
    

    And add Window_KeyDownPreview to your c# code:

      private void Window_KeyDownPreview(object sender, KeyEventArgs e)  
            {  
                switch (e.Key)  
                {  
                    case Key.NumPad0:  
                        Zero.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad1:  
                        One.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad2:  
                        Two.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad3:  
                        Three.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad4:  
                        Four.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad5:  
                        Five.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad6:  
                        Six.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad7:  
                        Seven.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad8:  
                        Eight.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.NumPad9:  
                        Nine.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Decimal:  
                        dec.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Add:  
                        Plus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Subtract:  
                        Minus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Multiply:  
                        Multiply.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Divide:  
                        Divide.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                    case Key.Enter:  
                        Equals.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));  
                        break;  
                }  
            }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Karen Payne MVP 35,026 Reputation points
    2021-03-25T13:29:44.947+00:00

    There are tons of code samples for this on GitHub, use the following with Google WPF-calculator GitHub which will produce several pages to choice from. And dependent on your skill level will dictate which one will assist you.

    Some are very simple to advance e.g. using MVVM pattern for advance.

    I picked a random from GitHub here which is simple and works. For keyboard, it recognizes operators on the numeric keypad, for = press Enter.

    81614-f1.png