Skip to main content

WPF C#/VB -
How to Make a Calculator App

Sections:

C#

// AZUL CODING ---------------------------------------
// WPF C#/VB - How to Make a Calculator App
// https://youtu.be/uZlUTJg21-w


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

namespace AzulCalculator;

public partial class MainWindow : Window
{
    private string currentInput = "0";
    private string currentOperation = "";
    private double firstNumber = 0;
    private bool isNewCalculation = true;
    private bool isOperationJustPressed = false;

    public MainWindow()
    {
        InitializeComponent();
        ResultTextBlock.Text = currentInput;
    }

    private void NumberButton_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;
        string digit = button.Content?.ToString() ?? "";

        // Prevent input if max length is reached
        if (currentInput.Length >= 12 && !isNewCalculation && !isOperationJustPressed)
            return;

        if (isNewCalculation || currentInput == "0" || isOperationJustPressed)
        {
            currentInput = digit;
            isNewCalculation = false;
            isOperationJustPressed = false;
        }
        else
        {
            currentInput += digit;
        }

        ResultTextBlock.Text = currentInput;
    }

    private void OperationButton_Click(object sender, RoutedEventArgs e)
    {
        Button button = (Button)sender;
        string operation = button.Content?.ToString() ?? "";

        // If user presses operations consecutively, just update the operation
        if (!isOperationJustPressed)
        {
            if (!string.IsNullOrEmpty(currentOperation))
            {
                CalculateResult();
            }
            else
            {
                firstNumber = double.Parse(currentInput);
            }
        }

        currentOperation = operation;
        isOperationJustPressed = true;
    }

    private void EqualButton_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(currentOperation) && !isOperationJustPressed)
        {
            CalculateResult();
            currentOperation = "";
            isNewCalculation = true;
        }
    }

    private void CalculateResult()
    {
        double secondNumber = double.Parse(currentInput);
        double result = 0;

        switch (currentOperation)
        {
            case "+":
                result = firstNumber + secondNumber;
                break;
            case "-":
                result = firstNumber - secondNumber;
                break;
            case "×":
                result = firstNumber * secondNumber;
                break;
            case "÷":
                if (secondNumber != 0)
                    result = firstNumber / secondNumber;
                else
                    MessageBox.Show("Cannot divide by zero", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                break;
        }

        if (Math.Abs(result) > 999999999 || Math.Abs(result) < 0.000001 && result != 0)
        {
            // Use scientific notation for very large or small numbers
            currentInput = result.ToString("E6");
        }
        else
        {
            string resultString = result.ToString();
            if (resultString.Contains('.') && resultString.Length > 10)
            {
                // Round to 8 significant digits
                currentInput = Math.Round(result, 8).ToString();
            }
            else
            {
                currentInput = resultString;
            }
        }

        ResultTextBlock.Text = currentInput;
        firstNumber = result;
    }

    private void ClearButton_Click(object sender, RoutedEventArgs e)
    {
        currentInput = "0";
        currentOperation = "";
        firstNumber = 0;
        isNewCalculation = true;
        isOperationJustPressed = false;
        ResultTextBlock.Text = currentInput;
    }

    private void DecimalButton_Click(object sender, RoutedEventArgs e)
    {
        // Prevent adding decimal if already at max length
        if (currentInput.Length >= 12 && !isNewCalculation && !isOperationJustPressed)
            return;

        if (isOperationJustPressed)
        {
            currentInput = "0.";
            isOperationJustPressed = false;
        }
        else if (!currentInput.Contains('.'))
        {
            isNewCalculation = false;
            currentInput += ".";
        }

        ResultTextBlock.Text = currentInput;
    }

    private void DeleteButton_Click(object sender, RoutedEventArgs e)
    {
        if (!isOperationJustPressed && currentInput.Length > 0 && !isNewCalculation)
        {
            currentInput = currentInput[..^1];
            if (string.IsNullOrEmpty(currentInput) || currentInput == "-")
            {
                currentInput = "0";
            }
            ResultTextBlock.Text = currentInput;
        }
    }

    private void PercentButton_Click(object sender, RoutedEventArgs e)
    {
        if (!isOperationJustPressed && !isNewCalculation)
        {
            double number = double.Parse(currentInput);
            number /= 100;
            currentInput = number.ToString();
            ResultTextBlock.Text = currentInput;
        }
    }

    private void PlusMinusButton_Click(object sender, RoutedEventArgs e)
    {
        if (!isOperationJustPressed && !isNewCalculation && currentInput != "0")
        {
            currentInput = currentInput.StartsWith('-') ? currentInput[1..] : "-" + currentInput;
            ResultTextBlock.Text = currentInput;
        }
    }
}

Help support the channel

VB.NET

' AZUL CODING ---------------------------------------
' WPF C#/VB - How to Make a Calculator App
' https://youtu.be/uZlUTJg21-w


Class MainWindow
    Private currentInput As String = "0"
    Private currentOperation As String = ""
    Private firstNumber As Double = 0
    Private isNewCalculation As Boolean = True
    Private isOperationJustPressed As Boolean = False

    Public Sub New()
        InitializeComponent()
        ResultTextBlock.Text = currentInput
    End Sub

    Private Sub NumberButton_Click(sender As Object, e As RoutedEventArgs)
        Dim button As Button = sender
        Dim digit As String = button.Content.ToString()

        ' Prevent input if max length is reached
        If currentInput.Length >= 12 AndAlso Not isNewCalculation AndAlso Not isOperationJustPressed Then
            Return
        End If

        If isNewCalculation OrElse currentInput = "0" OrElse isOperationJustPressed Then
            currentInput = digit
            isNewCalculation = False
            isOperationJustPressed = False
        Else
            currentInput += digit
        End If

        ResultTextBlock.Text = currentInput
    End Sub

    Private Sub OperationButton_Click(sender As Object, e As RoutedEventArgs)
        Dim button As Button = sender
        Dim operation As String = button.Content.ToString()

        ' If user presses operations consecutively, just update the operation
        If Not isOperationJustPressed Then
            If Not String.IsNullOrEmpty(currentOperation) Then
                CalculateResult()
            Else
                firstNumber = Double.Parse(currentInput)
            End If
        End If

        currentOperation = operation
        isOperationJustPressed = True
    End Sub

    Private Sub EqualButton_Click(sender As Object, e As RoutedEventArgs)
        If Not String.IsNullOrEmpty(currentOperation) AndAlso Not isOperationJustPressed Then
            CalculateResult()
            currentOperation = ""
            isNewCalculation = True
        End If
    End Sub

    Private Sub CalculateResult()
        Dim secondNumber As Double = Double.Parse(currentInput)
        Dim result As Double = 0

        Select Case currentOperation
            Case "+"
                result = firstNumber + secondNumber
            Case "-"
                result = firstNumber - secondNumber
            Case "×"
                result = firstNumber * secondNumber
            Case "÷"
                If secondNumber <> 0 Then
                    result = firstNumber / secondNumber
                Else
                    MessageBox.Show("Cannot divide by zero", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
                End If
        End Select

        If Math.Abs(result) > 999999999 OrElse (Math.Abs(result) < 0.000001 AndAlso result <> 0) Then
            ' Use scientific notation for very large or small numbers
            currentInput = result.ToString("E6")
        Else
            Dim resultString As String = result.ToString()
            If resultString.Contains("."c) AndAlso resultString.Length > 10 Then
                ' Round to 8 significant digits
                currentInput = Math.Round(result, 8).ToString()
            Else
                currentInput = resultString
            End If
        End If

        ResultTextBlock.Text = currentInput
        firstNumber = result
    End Sub

    Private Sub ClearButton_Click(sender As Object, e As RoutedEventArgs)
        currentInput = "0"
        currentOperation = ""
        firstNumber = 0
        isNewCalculation = True
        isOperationJustPressed = False
        ResultTextBlock.Text = currentInput
    End Sub

    Private Sub DecimalButton_Click(sender As Object, e As RoutedEventArgs)
        ' Prevent adding decimal if already at max length
        If currentInput.Length >= 12 AndAlso Not isNewCalculation AndAlso Not isOperationJustPressed Then
            Return
        End If

        If isOperationJustPressed Then
            currentInput = "0."
            isOperationJustPressed = False
        ElseIf Not currentInput.Contains("."c) Then
            isNewCalculation = False
            currentInput += "."
        End If

        ResultTextBlock.Text = currentInput
    End Sub

    Private Sub DeleteButton_Click(sender As Object, e As RoutedEventArgs)
        If Not isOperationJustPressed AndAlso currentInput.Length > 0 AndAlso Not isNewCalculation Then
            currentInput = currentInput.Substring(0, currentInput.Length - 1)
            If String.IsNullOrEmpty(currentInput) OrElse currentInput = "-" Then
                currentInput = "0"
            End If
            ResultTextBlock.Text = currentInput
        End If
    End Sub

    Private Sub PercentButton_Click(sender As Object, e As RoutedEventArgs)
        If Not isOperationJustPressed AndAlso Not isNewCalculation Then
            Dim number As Double = Double.Parse(currentInput)
            number /= 100
            currentInput = number.ToString()
            ResultTextBlock.Text = currentInput
        End If
    End Sub

    Private Sub PlusMinusButton_Click(sender As Object, e As RoutedEventArgs)
        If Not isOperationJustPressed AndAlso Not isNewCalculation AndAlso currentInput <> "0" Then
            currentInput = If(currentInput.StartsWith("-"c), currentInput.Substring(1), "-" + currentInput)
            ResultTextBlock.Text = currentInput
        End If
    End Sub
End Class

XAML

<!-- AZUL CODING --------------------------------------- -->
<!-- WPF C#/VB - How to Make a Calculator App -->
<!-- https://youtu.be/uZlUTJg21-w -->


<Window x:Class="AzulCalculator.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"
        mc:Ignorable="d"
        Title="Calculator - Azul Coding" Height="600" Width="400" WindowStartupLocation="CenterScreen" Background="#03506E" ResizeMode="CanMinimize">
    <Window.Resources>
        <Style x:Key="NumberButtonStyle" TargetType="Button">
            <Setter Property="FontSize" Value="32"/>
            <Setter Property="FontWeight" Value="SemiBold"/>
            <Setter Property="Foreground" Value="#03506E"/>
            <Setter Property="Background" Value="White"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}" CornerRadius="10" BorderThickness="0">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,3"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Opacity" Value="0.8"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="OperationButtonStyle" TargetType="Button" BasedOn="{StaticResource NumberButtonStyle}">
            <Setter Property="FontSize" Value="36"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="Background" Value="#49C8FC"/>
        </Style>

        <Style x:Key="FunctionButtonStyle" TargetType="Button" BasedOn="{StaticResource NumberButtonStyle}">
            <Setter Property="FontSize" Value="24"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Background" Value="#2F3C48"/>
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="5*"/>
        </Grid.RowDefinitions>
        <Border Grid.Row="0" Padding="20">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <TextBlock x:Name="OperationTextBlock" Grid.Row="0" Text="" FontSize="18" Foreground="LightGray" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,0,10"/>
                <TextBlock x:Name="ResultTextBlock" Grid.Row="1" Text="0" FontSize="48" FontWeight="SemiBold" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Center"/>
            </Grid>
        </Border>

        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Button Grid.Row="0" Grid.Column="0" Content="C" Click="ClearButton_Click" Style="{StaticResource FunctionButtonStyle}"/>
            <Button Grid.Row="0" Grid.Column="1" Content="±" Click="PlusMinusButton_Click" Style="{StaticResource FunctionButtonStyle}"/>
            <Button Grid.Row="0" Grid.Column="2" Content="%" Click="PercentButton_Click" Style="{StaticResource FunctionButtonStyle}"/>
            <Button Grid.Row="0" Grid.Column="3" Content="÷" Click="OperationButton_Click" Style="{StaticResource OperationButtonStyle}"/>

            <Button Grid.Row="1" Grid.Column="0" Content="7" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="1" Grid.Column="1" Content="8" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="1" Grid.Column="2" Content="9" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="1" Grid.Column="3" Content="×" Click="OperationButton_Click" Style="{StaticResource OperationButtonStyle}"/>

            <Button Grid.Row="2" Grid.Column="0" Content="4" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="2" Grid.Column="1" Content="5" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="2" Grid.Column="2" Content="6" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="2" Grid.Column="3" Content="-" Click="OperationButton_Click" Style="{StaticResource OperationButtonStyle}"/>

            <Button Grid.Row="3" Grid.Column="0" Content="1" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="3" Grid.Column="1" Content="2" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="3" Grid.Column="2" Content="3" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="3" Grid.Column="3" Content="+" Click="OperationButton_Click" Style="{StaticResource OperationButtonStyle}"/>

            <Button Grid.Row="4" Grid.Column="0" Content="⌫" Click="DeleteButton_Click" Style="{StaticResource FunctionButtonStyle}"/>
            <Button Grid.Row="4" Grid.Column="1" Content="0" Click="NumberButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="4" Grid.Column="2" Content="." Click="DecimalButton_Click" Style="{StaticResource NumberButtonStyle}"/>
            <Button Grid.Row="4" Grid.Column="3" Content="=" Click="EqualButton_Click" Style="{StaticResource OperationButtonStyle}"/>
        </Grid>
    </Grid>
</Window>