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

C# Windows Forms 강의 60편: TableLayoutPanel과 Dynamic Controls로 UI 동적 생성하기

by wawManager 2025. 4. 4.

 

1. 강의 개요

이번 강의에서는 TableLayoutPanel을 활용하여 동적으로 레이아웃을 생성하고,
Button, TextBox, Label 등의 컨트롤을 코드로 동적으로 추가하는 방법을 배웁니다.
TableLayoutPanel은 그리드 기반 레이아웃을 제공하며,
컨트롤을 체계적으로 배치하는 데 유용합니다.


2. 학습 목표

  • TableLayoutPanel의 기본 설정 및 사용법 이해
  • 컨트롤(Button, TextBox 등)을 동적으로 추가 및 제거
  • Cell 위치와 크기를 코드로 조정하는 방법 학습
  • 동적 UI를 활용한 간단한 데이터 입력 폼 구현

3. 기능 요구사항

필수 기능

1️⃣ TableLayoutPanel을 사용한 UI 레이아웃

  • 동적 그리드 기반의 레이아웃 설정

2️⃣ 컨트롤 동적 추가 및 제거

  • 버튼 클릭 시 새로운 컨트롤(TextBox, Label 등) 추가

3️⃣ 셀 크기 조정

  • 셀(Cell) 크기를 비율로 설정하여 가변적인 UI 제공

4️⃣ 데이터 입력 폼 구현

  • 여러 TextBox로 구성된 입력 폼 생성

4. 실습: TableLayoutPanel과 동적 컨트롤 추가

1️⃣ 폼 구성

  • 폼(Form) 이름: Form1
  • 컨트롤 배치

컨트롤 타입 이름 위치 크기

TableLayoutPanel tableLayoutPanel 폼 중앙 (400 x 300)
Button btnAddRow 폼 하단 왼쪽 (100 x 30)
Button btnRemoveRow 폼 하단 오른쪽 (100 x 30)

📌 폼 디자인 예시:

-------------------------------------------
| [Label]          [TextBox]               |
| [Label]          [TextBox]               |
| [Label]          [TextBox]               |
-------------------------------------------
| [추가 버튼]          [삭제 버튼]          |
-------------------------------------------

2️⃣ 코드 작성

Form1.cs

using System;
using System.Windows.Forms;

namespace WindowsFormsApp_TableLayoutPanel
{
    public partial class Form1 : Form
    {
        private int rowCount = 1; // 현재 행 개수

        public Form1()
        {
            InitializeComponent();
            InitializeTableLayoutPanel();
        }

        // TableLayoutPanel 초기화
        private void InitializeTableLayoutPanel()
        {
            tableLayoutPanel.ColumnCount = 2; // 2열 레이아웃
            tableLayoutPanel.RowCount = 1; // 초기 1행
            tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 30)); // 첫 번째 열 30%
            tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 70)); // 두 번째 열 70%
            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30)); // 초기 행 높이 30px
            tableLayoutPanel.Dock = DockStyle.Top;

            // 첫 번째 행에 Label과 TextBox 추가
            AddRow("Label 1", "TextBox 1");
        }

        // 새 행 추가
        private void btnAddRow_Click(object sender, EventArgs e)
        {
            rowCount++;
            tableLayoutPanel.RowCount += 1; // 행 개수 증가
            tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30)); // 새 행 높이 설정
            AddRow($"Label {rowCount}", $"TextBox {rowCount}");
        }

        // 마지막 행 제거
        private void btnRemoveRow_Click(object sender, EventArgs e)
        {
            if (tableLayoutPanel.RowCount > 1)
            {
                // 마지막 행의 컨트롤 제거
                for (int i = 0; i < tableLayoutPanel.ColumnCount; i++)
                {
                    var control = tableLayoutPanel.GetControlFromPosition(i, tableLayoutPanel.RowCount - 1);
                    if (control != null)
                    {
                        tableLayoutPanel.Controls.Remove(control);
                        control.Dispose();
                    }
                }

                // 행 제거
                tableLayoutPanel.RowCount -= 1;
                tableLayoutPanel.RowStyles.RemoveAt(tableLayoutPanel.RowStyles.Count - 1);
                rowCount--;
            }
        }

        // Label과 TextBox를 추가하는 메서드
        private void AddRow(string labelText, string textBoxName)
        {
            Label label = new Label
            {
                Text = labelText,
                Anchor = AnchorStyles.Left,
                AutoSize = true
            };

            TextBox textBox = new TextBox
            {
                Name = textBoxName,
                Anchor = AnchorStyles.Left | AnchorStyles.Right
            };

            tableLayoutPanel.Controls.Add(label, 0, tableLayoutPanel.RowCount - 1); // 첫 번째 열
            tableLayoutPanel.Controls.Add(textBox, 1, tableLayoutPanel.RowCount - 1); // 두 번째 열
        }
    }
}

Form1.Designer.cs

namespace WindowsFormsApp_TableLayoutPanel
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private TableLayoutPanel tableLayoutPanel;
        private Button btnAddRow;
        private Button btnRemoveRow;

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

        private void InitializeComponent()
        {
            this.tableLayoutPanel = new TableLayoutPanel();
            this.btnAddRow = new Button();
            this.btnRemoveRow = new Button();

            // TableLayoutPanel 설정
            this.tableLayoutPanel.Location = new System.Drawing.Point(10, 10);
            this.tableLayoutPanel.Size = new System.Drawing.Size(400, 300);

            // 추가 버튼 설정
            this.btnAddRow.Location = new System.Drawing.Point(10, 320);
            this.btnAddRow.Size = new System.Drawing.Size(100, 30);
            this.btnAddRow.Text = "행 추가";
            this.btnAddRow.Click += new System.EventHandler(this.btnAddRow_Click);

            // 삭제 버튼 설정
            this.btnRemoveRow.Location = new System.Drawing.Point(120, 320);
            this.btnRemoveRow.Size = new System.Drawing.Size(100, 30);
            this.btnRemoveRow.Text = "행 삭제";
            this.btnRemoveRow.Click += new System.EventHandler(this.btnRemoveRow_Click);

            // Form 설정
            this.ClientSize = new System.Drawing.Size(420, 360);
            this.Controls.Add(this.tableLayoutPanel);
            this.Controls.Add(this.btnAddRow);
            this.Controls.Add(this.btnRemoveRow);
            this.Text = "TableLayoutPanel 동적 UI 생성";
        }
    }
}

3️⃣ 실행 결과

1️⃣ 기본 UI 구성

  • 초기 화면에는 1개의 Label과 TextBox가 표시

2️⃣ 행 추가 버튼 클릭

  • "행 추가" 버튼 클릭 시 새로운 Label과 TextBox가 추가

3️⃣ 행 삭제 버튼 클릭

  • "행 삭제" 버튼 클릭 시 마지막 행이 제거

4️⃣ 셀 크기 조정

  • 첫 번째 열 30%, 두 번째 열 70%로 비율 유지

5. 주요 개념 요약

  • TableLayoutPanel: 동적 그리드 기반의 UI 레이아웃 컨트롤
  • RowStyles & ColumnStyles: 셀 크기를 비율 또는 고정값으로 설정
  • Controls.Add: 특정 위치에 컨트롤 추가
  • GetControlFromPosition: 지정된 셀에 위치한 컨트롤 반환