본문 바로가기
C#

[C#][.NET Core] 윈도우 계산기 앱 만들기

by teamnova 2024. 3. 15.

오늘은 visual studio 2022를 사용해 윈도우 계산기 앱을 만들어 보겠습니다.

 

먼저 Visual Studio 2022를 실행한 뒤 우측 시작 메뉴에서 새 프로젝트 만들기를 눌러주세요.

 

그리고 Windows Forms 앱 C#을 선택하고 원하는 디렉토리에 프로젝트 이름을 설정해줍니다.

 

그 뒤 원하는 프레임워크를 선택하는 저는 .NET 8.0으로 하겠습니다.

 

그럼 다음과 같이 윈도우 폼 템플릿이 생성되고 여러 샘플 파일이 생성됩니다.(Form1.cs, Form1.Desinger.cd, Program.cs 등)

Program.cs : 앱의 진입점을 포함하는 파일로 앱을 시작하고 초기 설정을 수행하는 코드를 담고 있다.

namespace winFormApp;

static class Program
{
    //  The main entry point for the application.
    [STAThread] // 단일 스레드 아파트먼트 모델로 지정(윈도우라는 다중 스레드 환경에서 안전하게 작동할 수 있도록 함)
    static void Main()
    {
        ApplicationConfiguration.Initialize(); // 앱의 기본 설정 초기화(폰트, DPI, 테마 등)
        Application.Run(new Form1()); // 앱의 메인 루프를 시작하고 Form1의 인스턴스를 생성하여 화면에 표시한다.
    }    
}

 

Form1.cs : 폼의 메인 클래스 정의 파일로 사용자가 직접 작업하는 로직, 이벤트 핸들러, 메서드 등을 포함한다.

namespace winFormApp;

// 사용자 코드를 위한 Form1.cs

// public : 다른 클래스와 어셈블리에서 접근 가능한 클래스임을 의미
// partial : 여러 파일에 걸처 클래스가 정의되어 있음을 표시
// :Form : Form 클래스를 상속 받는 것을 의미한다.
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent(); // Form에 대한 기본적인 초기화 코드를 포함한다.
    }
}

 

Form1.designer.cs : 폼의 디자인과 관련된 자동 생성 코드를 포함한다.(Windows Forms Desinger에서 생성 및 수정)

namespace winFormApp;

// 디자이너 코드를 위한 Form1.Designer.cs

partial class Form1
{
    // components는 폼에 추가된 모든 컴포넌트와 컨트롤을 포함하는 컨테이너로 폼의 구성 요소를 관리하는 데 사용한다.
    private System.ComponentModel.IContainer components = null;

    // Dispose 메소드는 폼과 그 컴포넌트의 리소스 정리를 담당하고 <param name="disposing">true일 떄 관리되는 리소스가 해제되어야 한다.
    // 결국 이 메소드는 폼이 닫힐 때 호출되는 메소드이다.
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    // 디자이너 코드의 영역을 시작하는 지시자
    #region Windows Form Designer generated code

    // 폼의 초기 구성요소를 설정하는 메소드로 컴포넌트의 기본 속성들을 설정하고, 컨트롤을 폼에 추가한다.
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container(); // 컴포넌트 컨테이너 초기화
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; // 폼 스케일링 모드 설정(폰트 크기 기반)
        this.ClientSize = new System.Drawing.Size(800, 450); // 폼의 클라이언트 영역 크기를 설정
        this.Text = "Form1"; // 폼의 제목 표시줄 텍스트 설정
    }

    // 디자이너 코드의 영역을 끝내는 지시자
    #endregion
}

 

 

이제 계산기를 만들기 위해 폼을 만들어 보겠습니다.

Form1.cs의 디자인 탭을 띄우고 상단 메뉴에서 보기 > 도구상자를 클릭합니다.

그리고 공용 컨트롤 메뉴로 가 텍스트 박스와 버튼을 드래그해서 폼 위로 올려보겠습니다.

 

이제 계산기처럼 사용하기 위해 보여지는 텍스트를 바꿔보겠습니다.

Form1.Designer.cs 파일로 가면 InitializedComponent() 메소드 내부에 각 컴포넌트들이 초기화되어 있는 것을 확인할 수 있습니다. 거기서 button 변수들의 Text값을 변경하면 실제 폼에 보여지는 버튼의 값들을 변경할 수 있습니다.

 

 

이제 이 버튼들을 사용해 텍스트 입력 창에 입력 값을 넣는 법을 알아보겠습니다.

Form1.cs 파일의 코드를 다음과 같이 작성해보겠습니다.

using System.Diagnostics;

namespace CalculatorApp
{
    public partial class Form1 : Form
    {

        private string input = string.Empty; // 사용자의 입력을 저장합니다.
        private string num1; // 숫자1을 저장합니다.
        private string num2; // 숫자2를 저장합니다.
        private char operation; // 방금 입력한 연산자를 임시 저장합니다.
        private char lastOperation; // 마지막으로 입력된 연산자를 저장합니다.
        private bool num1turn; // 현재 입력될 숫자의 차례를 구분합니다.

        public Form1()
        {
            num1turn = true;

            InitializeComponent(); // 폼에 사용되는 각 컴포넌트 초기화

            button1.Click += NumBtn_Click; // button1 Click에 NumBtn_Click함수를 연결
            button2.Click += NumBtn_Click; 
            button3.Click += NumBtn_Click;
            button4.Click += NumBtn_Click;
            button5.Click += NumBtn_Click;
            button6.Click += NumBtn_Click;
            button7.Click += NumBtn_Click;
            button8.Click += NumBtn_Click;
            button9.Click += NumBtn_Click;
            button10.Click += NumBtn_Click;
            button11.Click += OperationBtn_Click; // button1 Click에 OperationBtn_Click 연결
            button12.Click += OperationBtn_Click;
            button13.Click += OperationBtn_Click;
            button14.Click += OperationBtn_Click;
            button15.Click += EquallBtn_Click; // button1 Click에 EquallBtn_Click 연결
        }

        // 숫자 버튼 클릭 메소드
        private void NumBtn_Click(object sender, EventArgs e)
        {
            // sender는 메소드를 실행시키는 주체로 클릭된 객체이다.
            // EventArgs는 .NET 프레임워크에서 이벤트 데이터를 클래스의 인스턴스로 나타낼 때 사용되는 기본 클래스이다.(데이터 전달용)

            Button btn = sender as Button; // 실행자 버튼타입으로 변환
            string inputNum = btn.Text.ToString(); // 버튼 텍스트 값 추출해 변수에 저장
            textBox1.Text += inputNum; // inputNum 변수 값 텍스트 박스에 추가

            if (num1turn) // 첫 번째 숫자 입력 턴일 경우
            {
                num1 += inputNum; // 입력한 숫자 두 번째 숫자에 저장
            }
            else // 두 번째 숫자 입력 턴일 경우
            {
                num2 += inputNum; // 입력한 숫자 두 번째 숫자에 저장
            }

            if(operation != '\0')
            {
                lastOperation = operation;
                operation = '\0';
            }

            // 디버그 출력에 로그를 찍습니다.
            Debug.WriteLine($"num1 =  {num1}");
        }

        // 연산자 버튼 클릭 메소드
        private void OperationBtn_Click(object sender, EventArgs e)
        {
            Button btn = sender as Button;
            
            if (operation == '\0') // operation 변수에 값이 들어있는지 확인 후 값이 없으면 코드 실행
            {
                operation = btn.Text[0]; // 연산자 변수에 값 저장
                textBox1.Text += operation; // 텍스트 박스에 연산자 입력

                if (num1turn)
                {
                    num1turn = false; // 두 번째 숫자에게 턴 넘겨주기
                }
            }
            else // operation 변수에 값이 있을 경우 대체
            {
                textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1); // 텍스트 박스에 이미 입력된 연산자 제거

                operation = btn.Text[0]; // 연산자 변수에 값 저장
                textBox1.Text += operation; // 텍스트 박스에 연산자 입력
            }

        }

        // = 버튼 클릭 메소드
        private void EquallBtn_Click(object sender, EventArgs e)
        {
            double result = 0;
            if (num1.Length > 0 && num2.Length > 0) // 이미 두 숫자값이 입력이 된 상태일 경우
            {
                switch (lastOperation) // 마지막에 사용된 연산자에 따라 계산
                {
                    case '+':
                        result = double.Parse(num1) + double.Parse(num2);
                        break;
                    case '-':
                        result = double.Parse(num1) - double.Parse(num2);
                        break;
                    case '*':
                        result = double.Parse(num1) * double.Parse(num2);
                        break;
                    case '/':
                        result = double.Parse(num1) / double.Parse(num2);
                        break;
                }
            }

            num1 = textBox1.Text = result.ToString(); // 계산 결과값을 텍스트 박스에 띄워주고 num1 변수에 값 저장
            num2 = ""; // num2 변수 지워주기
            num1turn = true; // 다시 숫자 입력 턴 첫 번째 숫자로 이동
        }

    }
}

 

 

이렇게 작성한 뒤 앱을 빌드해 실행하면 다음과 같이 간단한 계산기 기능을 만들 수 있습니다.

 

 

감사합니다.