본문 바로가기
Study/C#

C# Windows Forms 강의 31편: ContextMenuStrip으로 동적 컨텍스트 메뉴 구현

by wawManager 2025. 3. 6.
728x90

1. 강의 개요

이번 강의에서는 ContextMenuStrip을 사용하여 동적 컨텍스트 메뉴를 구현하는 방법을 학습합니다.
ContextMenuStrip은 폼의 특정 요소에 마우스 오른쪽 버튼을 클릭했을 때 표시되는 메뉴를 제공합니다.


2. 학습 목표

  1. ContextMenuStrip을 설정하고 이벤트 처리 구현.
  2. 동적으로 메뉴 항목을 추가 및 제거.
  3. DataGridView와 연동하여 행 선택 및 삭제 기능 구현.

3. ContextMenuStrip이란?

ContextMenuStrip은 특정 컨트롤에 연관된 상황별(컨텍스트) 메뉴를 생성할 수 있는 Windows Forms 컨트롤입니다.

  • 사용자 친화적인 작업 메뉴를 제공.
  • 동적으로 메뉴 항목 추가 및 삭제 가능.

ContextMenuStrip 주요 속성 및 메서드

속성/메서드 설명 예제

Items 메뉴 항목을 관리하는 컬렉션 contextMenuStrip1.Items.Add("항목");
Show() 지정된 위치에 컨텍스트 메뉴 표시 contextMenuStrip1.Show(this, location);

주요 이벤트

이벤트 설명 예제

Opening 컨텍스트 메뉴가 열리기 직전에 발생 contextMenuStrip1.Opening += ...;
ItemClicked 메뉴 항목이 클릭되었을 때 발생 contextMenuStrip1.ItemClicked += ...;

4. 실습: ContextMenuStrip을 사용한 동적 메뉴 구현

요구사항

  1. DataGridView에 ContextMenuStrip 연결.
  2. "행 삭제" 메뉴로 선택된 행 삭제.
  3. 동적으로 메뉴 항목 추가 및 제거.

폼 구성

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

DataGridView dataGridView1 (없음) 상단 (400 x 200)

코드 작성

1. 데이터 클래스 정의

public class Product
{
    public string Name { get; set; }
    public int Quantity { get; set; }
    public double Price { get; set; }
}

2. Form1.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private List<Product> productList;
        private ContextMenuStrip contextMenuStrip1;

        public Form1()
        {
            InitializeComponent();
            InitializeDataGridView();
            InitializeContextMenu();
        }

        private void InitializeDataGridView()
        {
            // 데이터 초기화
            productList = new List<Product>
            {
                new Product { Name = "사과", Quantity = 10, Price = 1.2 },
                new Product { Name = "바나나", Quantity = 15, Price = 0.8 },
                new Product { Name = "체리", Quantity = 20, Price = 2.5 }
            };

            // DataGridView 설정
            dataGridView1.DataSource = productList;
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        }

        private void InitializeContextMenu()
        {
            // ContextMenuStrip 생성
            contextMenuStrip1 = new ContextMenuStrip();

            // 메뉴 항목 추가
            var deleteMenuItem = new ToolStripMenuItem("행 삭제");
            deleteMenuItem.Click += DeleteMenuItem_Click;

            var customMenuItem = new ToolStripMenuItem("커스텀 동작");
            customMenuItem.Click += CustomMenuItem_Click;

            contextMenuStrip1.Items.Add(deleteMenuItem);
            contextMenuStrip1.Items.Add(customMenuItem);

            // DataGridView와 ContextMenuStrip 연결
            dataGridView1.ContextMenuStrip = contextMenuStrip1;
        }

        // "행 삭제" 메뉴 클릭 이벤트
        private void DeleteMenuItem_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow != null)
            {
                int index = dataGridView1.CurrentRow.Index;
                productList.RemoveAt(index);
                dataGridView1.DataSource = null;
                dataGridView1.DataSource = productList;
            }
            else
            {
                MessageBox.Show("삭제할 행을 선택하세요.", "알림");
            }
        }

        // "커스텀 동작" 메뉴 클릭 이벤트
        private void CustomMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("커스텀 메뉴 동작이 실행되었습니다!", "알림");
        }
    }
}

3. Form1.Designer.cs

namespace WindowsFormsApp1
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;
        private DataGridView dataGridView1;

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

        private void InitializeComponent()
        {
            this.dataGridView1 = new DataGridView();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();

            // dataGridView1
            this.dataGridView1.Location = new System.Drawing.Point(20, 20);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(400, 200);
            this.dataGridView1.TabIndex = 0;

            // Form1
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(450, 250);
            this.Controls.Add(this.dataGridView1);
            this.Name = "Form1";
            this.Text = "ContextMenuStrip 예제";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);
        }
    }
}

5. 실행 결과

  1. 초기 상태
    • DataGridView에 초기 데이터(사과, 바나나, 체리)가 표시됩니다.
  2. 컨텍스트 메뉴 열기
    • DataGridView에서 행을 선택한 후 마우스 오른쪽 버튼 클릭 → "행 삭제"와 "커스텀 동작" 메뉴가 표시됩니다.
  3. 행 삭제
    • "행 삭제" 메뉴 클릭 → 선택된 행이 삭제됩니다.
  4. 커스텀 동작
    • "커스텀 동작" 메뉴 클릭 → 알림 메시지가 표시됩니다.

6. 주요 개념 요약

  1. ContextMenuStrip: 특정 컨트롤에 상황별 메뉴를 제공하는 컨트롤.
  2. 동적 메뉴 항목 추가: ToolStripMenuItem을 생성하여 컨텍스트 메뉴에 추가 가능.
  3. 컨트롤 연동: DataGridView와 ContextMenuStrip을 연결하여 행별 작업 수행 가능.

 

728x90