본문 바로가기
📁 [4] 개발자 정보 & 코드 노트/C#

C# Windows Forms 강의 52편: To-Do List 애플리케이션 제작

by wawManager 2025. 3. 27.

1. 강의 개요

이번 강의에서는 Windows Forms를 사용해 간단한 To-Do List 애플리케이션을 제작합니다.
사용자가 할 일을 추가, 수정, 삭제할 수 있으며, 데이터는 파일로 저장하고 불러옵니다. 이를 통해 ListBox, File I/O, Button 이벤트 활용법을 학습합니다.


2. 학습 목표

  1. ListBox를 사용해 할 일 목록 관리.
  2. 할 일 추가, 수정, 삭제 기능 구현.
  3. 텍스트 파일로 데이터 저장 및 불러오기.

3. To-Do List 기능 요구사항

  1. 할 일 관리 기능
    • 추가: 새 할 일을 목록에 추가.
    • 수정: 선택한 할 일을 편집.
    • 삭제: 선택한 할 일을 목록에서 제거.
  2. 파일 관리 기능
    • 저장: 현재 목록을 텍스트 파일로 저장.
    • 불러오기: 기존 파일에서 할 일 목록을 로드.

4. 실습: To-Do List 애플리케이션 구현

폼 구성

컨트롤 타입 이름 텍스트 위치 크기

ListBox lstToDo (없음) 왼쪽 상단 (200 x 250)
TextBox txtNewTask (없음) 오른쪽 상단 (200 x 30)
Button btnAdd "추가" 오른쪽 아래 텍스트박스 (80 x 30)
Button btnEdit "수정" 오른쪽 중단 텍스트박스 (80 x 30)
Button btnDelete "삭제" 오른쪽 아래 텍스트박스 (80 x 30)
Button btnSave "저장" 아래 왼쪽 버튼 (80 x 30)
Button btnLoad "불러오기" 아래 오른쪽 버튼 (80 x 30)

코드 작성


1. Form1.cs

using System;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeEvents();
        }

        private void InitializeEvents()
        {
            btnAdd.Click += BtnAdd_Click;
            btnEdit.Click += BtnEdit_Click;
            btnDelete.Click += BtnDelete_Click;
            btnSave.Click += BtnSave_Click;
            btnLoad.Click += BtnLoad_Click;
        }

        // "추가" 버튼 클릭 이벤트
        private void BtnAdd_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txtNewTask.Text))
            {
                lstToDo.Items.Add(txtNewTask.Text); // ListBox에 새 항목 추가
                txtNewTask.Clear(); // 텍스트 박스 초기화
            }
            else
            {
                MessageBox.Show("할 일을 입력하세요.", "알림");
            }
        }

        // "수정" 버튼 클릭 이벤트
        private void BtnEdit_Click(object sender, EventArgs e)
        {
            if (lstToDo.SelectedItem != null && !string.IsNullOrWhiteSpace(txtNewTask.Text))
            {
                int selectedIndex = lstToDo.SelectedIndex;
                lstToDo.Items[selectedIndex] = txtNewTask.Text; // 선택한 항목 수정
                txtNewTask.Clear();
            }
            else
            {
                MessageBox.Show("수정할 항목을 선택하고 내용을 입력하세요.", "알림");
            }
        }

        // "삭제" 버튼 클릭 이벤트
        private void BtnDelete_Click(object sender, EventArgs e)
        {
            if (lstToDo.SelectedItem != null)
            {
                lstToDo.Items.Remove(lstToDo.SelectedItem); // 선택한 항목 삭제
            }
            else
            {
                MessageBox.Show("삭제할 항목을 선택하세요.", "알림");
            }
        }

        // "저장" 버튼 클릭 이벤트
        private void BtnSave_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt";
                saveFileDialog.Title = "할 일 목록 저장";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName))
                    {
                        foreach (var item in lstToDo.Items)
                        {
                            writer.WriteLine(item.ToString());
                        }
                    }
                    MessageBox.Show("파일이 저장되었습니다.", "저장 완료");
                }
            }
        }

        // "불러오기" 버튼 클릭 이벤트
        private void BtnLoad_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt";
                openFileDialog.Title = "할 일 목록 불러오기";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    lstToDo.Items.Clear(); // 기존 항목 초기화
                    using (StreamReader reader = new StreamReader(openFileDialog.FileName))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            lstToDo.Items.Add(line);
                        }
                    }
                }
            }
        }
    }
}

2. Form1.Designer.cs

namespace WindowsFormsApp1
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private ListBox lstToDo;
        private TextBox txtNewTask;
        private Button btnAdd;
        private Button btnEdit;
        private Button btnDelete;
        private Button btnSave;
        private Button btnLoad;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.lstToDo = new ListBox();
            this.txtNewTask = new TextBox();
            this.btnAdd = new Button();
            this.btnEdit = new Button();
            this.btnDelete = new Button();
            this.btnSave = new Button();
            this.btnLoad = new Button();
            this.SuspendLayout();

            // lstToDo
            this.lstToDo.Location = new System.Drawing.Point(10, 10);
            this.lstToDo.Name = "lstToDo";
            this.lstToDo.Size = new System.Drawing.Size(200, 250);

            // txtNewTask
            this.txtNewTask.Location = new System.Drawing.Point(230, 10);
            this.txtNewTask.Name = "txtNewTask";
            this.txtNewTask.Size = new System.Drawing.Size(200, 30);

            // btnAdd
            this.btnAdd.Location = new System.Drawing.Point(230, 50);
            this.btnAdd.Name = "btnAdd";
            this.btnAdd.Size = new System.Drawing.Size(80, 30);
            this.btnAdd.Text = "추가";

            // btnEdit
            this.btnEdit.Location = new System.Drawing.Point(230, 90);
            this.btnEdit.Name = "btnEdit";
            this.btnEdit.Size = new System.Drawing.Size(80, 30);
            this.btnEdit.Text = "수정";

            // btnDelete
            this.btnDelete.Location = new System.Drawing.Point(230, 130);
            this.btnDelete.Name = "btnDelete";
            this.btnDelete.Size = new System.Drawing.Size(80, 30);
            this.btnDelete.Text = "삭제";

            // btnSave
            this.btnSave.Location = new System.Drawing.Point(10, 280);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(80, 30);
            this.btnSave.Text = "저장";

            // btnLoad
            this.btnLoad.Location = new System.Drawing.Point(120, 280);
            this.btnLoad.Name = "btnLoad";
            this.btnLoad.Size = new System.Drawing.Size(80, 30);
            this.btnLoad.Text = "불러오기";

            // Form1
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(450, 330);
            this.Controls.Add(this.btnLoad);
            this.Controls.Add(this.btnSave);
            this.Controls.Add(this.btnDelete);
            this.Controls.Add(this.btnEdit);
            this.Controls.Add(this.btnAdd);
            this.Controls.Add(this.txtNewTask);
            this.Controls.Add(this.lstToDo);
            this.Name = "Form1";
            this.Text = "To-Do List";
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    }
}

5. 실행 결과

  1. 초기 상태
    • ListBox는 비어 있고, 텍스트 입력란과 버튼들이 표시됩니다.
  2. 할 일 추가
    • 텍스트를 입력하고 "추가" 버튼 클릭 → 새 항목이 ListBox에 추가됩니다.
  3. 할 일 수정
    • ListBox에서 항목을 선택하고 텍스트를 수정 후 "수정" 버튼 클릭 → 항목이 업데이트됩니다.
  4. 할 일 삭제
    • ListBox에서 항목을 선택하고 "삭제" 버튼 클릭 → 항목이 제거됩니다.
  5. 저장 및 불러오기
    • "저장" 버튼 클릭 → 텍스트 파일로 목록이 저장됩니다.
    • "불러오기" 버튼 클릭 → 저장된 파일에서 목록이 로드됩니다.

6. 주요 개념 요약

  1. ListBox 컨트롤
    • Items.Add, Items.Remove를 사용해 항목 추가/삭제.
    • SelectedItem으로 선택한 항목 가져오기.
  2. File I/O
    • StreamWriter와 StreamReader로 파일 저장 및 불러오기 구현.
  3. Button 이벤트 처리
    • 버튼 클릭 이벤트를 통해 사용자 입력을 ListBox와 파일로 관리.