언어 자료구조 알고리즘/프로그래밍 실습

[C#, Widows Form 실습] Wafer 등록기 - 반도체 제어시스템 시뮬

언제나휴일 2020. 11. 24. 15:33
반응형

Wafer 등록기를 만들어보자.

Wafer에는 제조회사, 제품명, 방향(100,110,111), 반경, 타입(P타입, N타입)을 속성으로 갖는다.

다음과 같은 폼에 의해 사용자와 상호작용하는 Wafer 등록기를 작성하자.

 

[그림] 컨트롤 배치

1. 프로젝트 생성

Wafer Manager 프로젝트를 생성하자.

프로젝트 유형:  Windows Forms 앱(.NET Framework) 

2. Wafer 클래스 추가

프로젝트 컨텍스트 메뉴(오른쪽 마우스 클릭 시 나오는 메뉴)에서 새 항목을 선택한 후 Wafer 클래스를 추가하자.

그리고 다음과 같이 클래스를 정의한다.

namespace Wafer_Manager
{
    public class Wafer
    {
        public string Company
        {
            get;//가져오기
            set;//설정하기
            //private set; //외부에서 설정하기를 막고자 할 때
        }
        public string Name
        {
            get;
            set;
        }
        public WDirection WDir
        {
            get;
            set;
        }
        public double Radius
        {
            get;
            set;
        }
        public bool PType
        {
            get;
            set;
        }
        public Wafer(string company, string name,
            WDirection wdir, double radius, bool ptype)
        {
            Company = company;
            Name = name;
            WDir = wdir;
            Radius = radius;
            PType = ptype;
        }
    }
    public enum WDirection
    {
        WD_111,WD_100, WD_110
    }
}

3. 컨트롤 배치

"[그림] 컨트롤 배치"처럼 자식 컨트롤을 배치합니다. 

btn_remove의 Enable 속성은 False로 설정하세요.

4. 이벤트 핸들러 등록

세 개의 버튼의 Click 이벤트 핸들러와 lbox_wafer의 선택 항목 변경 이벤트 핸들러를 등록하세요.

현재까지의 Fom1.Designer.cs 코드는 다음과 같습니다.

namespace Wafer_Manager
{
    partial class Form1
    {
        /// <summary>
        /// 필수 디자이너 변수입니다.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 사용 중인 모든 리소스를 정리합니다.
        /// </summary>
        /// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form 디자이너에서 생성한 코드

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다. 
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
        /// </summary>
        private void InitializeComponent()
        {
            this.lbox_wafer = new System.Windows.Forms.ListBox();
            this.label1 = new System.Windows.Forms.Label();
            this.cbox_company = new System.Windows.Forms.ComboBox();
            this.btn_com_add = new System.Windows.Forms.Button();
            this.label2 = new System.Windows.Forms.Label();
            this.tbox_name = new System.Windows.Forms.TextBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.rb_111 = new System.Windows.Forms.RadioButton();
            this.rb_110 = new System.Windows.Forms.RadioButton();
            this.rb_100 = new System.Windows.Forms.RadioButton();
            this.label3 = new System.Windows.Forms.Label();
            this.nud_radius = new System.Windows.Forms.NumericUpDown();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.rb_n = new System.Windows.Forms.RadioButton();
            this.rb_p = new System.Windows.Forms.RadioButton();
            this.btn_add = new System.Windows.Forms.Button();
            this.btn_remove = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).BeginInit();
            this.groupBox2.SuspendLayout();
            this.SuspendLayout();
            // 
            // lbox_wafer
            // 
            this.lbox_wafer.FormattingEnabled = true;
            this.lbox_wafer.ItemHeight = 24;
            this.lbox_wafer.Location = new System.Drawing.Point(13, 24);
            this.lbox_wafer.Name = "lbox_wafer";
            this.lbox_wafer.Size = new System.Drawing.Size(199, 388);
            this.lbox_wafer.TabIndex = 0;
            this.lbox_wafer.SelectedIndexChanged += new System.EventHandler(this.lbox_wafer_SelectedIndexChanged);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(231, 36);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(90, 24);
            this.label1.TabIndex = 1;
            this.label1.Text = "제조사:";
            this.label1.Click += new System.EventHandler(this.label1_Click);
            // 
            // cbox_company
            // 
            this.cbox_company.FormattingEnabled = true;
            this.cbox_company.Location = new System.Drawing.Point(315, 33);
            this.cbox_company.Name = "cbox_company";
            this.cbox_company.Size = new System.Drawing.Size(192, 32);
            this.cbox_company.TabIndex = 2;
            // 
            // btn_com_add
            // 
            this.btn_com_add.Location = new System.Drawing.Point(514, 33);
            this.btn_com_add.Name = "btn_com_add";
            this.btn_com_add.Size = new System.Drawing.Size(119, 32);
            this.btn_com_add.TabIndex = 3;
            this.btn_com_add.Text = "추가";
            this.btn_com_add.UseVisualStyleBackColor = true;
            this.btn_com_add.Click += new System.EventHandler(this.btn_com_add_Click);
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(231, 89);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(90, 24);
            this.label2.TabIndex = 4;
            this.label2.Text = "제품명:";
            // 
            // tbox_name
            // 
            this.tbox_name.Location = new System.Drawing.Point(315, 86);
            this.tbox_name.Name = "tbox_name";
            this.tbox_name.Size = new System.Drawing.Size(192, 35);
            this.tbox_name.TabIndex = 5;
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.rb_111);
            this.groupBox1.Controls.Add(this.rb_110);
            this.groupBox1.Controls.Add(this.rb_100);
            this.groupBox1.Location = new System.Drawing.Point(235, 149);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(398, 66);
            this.groupBox1.TabIndex = 6;
            this.groupBox1.TabStop = false;
            // 
            // rb_111
            // 
            this.rb_111.AutoSize = true;
            this.rb_111.Location = new System.Drawing.Point(233, 32);
            this.rb_111.Name = "rb_111";
            this.rb_111.Size = new System.Drawing.Size(67, 28);
            this.rb_111.TabIndex = 2;
            this.rb_111.TabStop = true;
            this.rb_111.Text = "111";
            this.rb_111.UseVisualStyleBackColor = true;
            // 
            // rb_110
            // 
            this.rb_110.AutoSize = true;
            this.rb_110.Location = new System.Drawing.Point(134, 32);
            this.rb_110.Name = "rb_110";
            this.rb_110.Size = new System.Drawing.Size(67, 28);
            this.rb_110.TabIndex = 1;
            this.rb_110.TabStop = true;
            this.rb_110.Text = "110";
            this.rb_110.UseVisualStyleBackColor = true;
            // 
            // rb_100
            // 
            this.rb_100.AutoSize = true;
            this.rb_100.Location = new System.Drawing.Point(26, 35);
            this.rb_100.Name = "rb_100";
            this.rb_100.Size = new System.Drawing.Size(67, 28);
            this.rb_100.TabIndex = 0;
            this.rb_100.TabStop = true;
            this.rb_100.Text = "100";
            this.rb_100.UseVisualStyleBackColor = true;
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(235, 244);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(66, 24);
            this.label3.TabIndex = 7;
            this.label3.Text = "반경:";
            // 
            // nud_radius
            // 
            this.nud_radius.Location = new System.Drawing.Point(327, 242);
            this.nud_radius.Name = "nud_radius";
            this.nud_radius.Size = new System.Drawing.Size(201, 35);
            this.nud_radius.TabIndex = 8;
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.rb_n);
            this.groupBox2.Controls.Add(this.rb_p);
            this.groupBox2.Location = new System.Drawing.Point(235, 291);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(398, 73);
            this.groupBox2.TabIndex = 9;
            this.groupBox2.TabStop = false;
            // 
            // rb_n
            // 
            this.rb_n.AutoSize = true;
            this.rb_n.Location = new System.Drawing.Point(192, 35);
            this.rb_n.Name = "rb_n";
            this.rb_n.Size = new System.Drawing.Size(90, 28);
            this.rb_n.TabIndex = 1;
            this.rb_n.TabStop = true;
            this.rb_n.Text = "N타입";
            this.rb_n.UseVisualStyleBackColor = true;
            // 
            // rb_p
            // 
            this.rb_p.AutoSize = true;
            this.rb_p.Location = new System.Drawing.Point(7, 35);
            this.rb_p.Name = "rb_p";
            this.rb_p.Size = new System.Drawing.Size(91, 28);
            this.rb_p.TabIndex = 0;
            this.rb_p.TabStop = true;
            this.rb_p.Text = "P타입";
            this.rb_p.UseVisualStyleBackColor = true;
            // 
            // btn_add
            // 
            this.btn_add.Location = new System.Drawing.Point(235, 370);
            this.btn_add.Name = "btn_add";
            this.btn_add.Size = new System.Drawing.Size(166, 35);
            this.btn_add.TabIndex = 10;
            this.btn_add.Text = "추가";
            this.btn_add.UseVisualStyleBackColor = true;
            this.btn_add.Click += new System.EventHandler(this.btn_add_Click);
            // 
            // btn_remove
            // 
            this.btn_remove.Enabled = false;
            this.btn_remove.Location = new System.Drawing.Point(407, 370);
            this.btn_remove.Name = "btn_remove";
            this.btn_remove.Size = new System.Drawing.Size(166, 35);
            this.btn_remove.TabIndex = 11;
            this.btn_remove.Text = "삭제";
            this.btn_remove.UseVisualStyleBackColor = true;
            this.btn_remove.Click += new System.EventHandler(this.btn_remove_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 24F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(655, 426);
            this.Controls.Add(this.btn_remove);
            this.Controls.Add(this.btn_add);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.nud_radius);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.tbox_name);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.btn_com_add);
            this.Controls.Add(this.cbox_company);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.lbox_wafer);
            this.Font = new System.Drawing.Font("굴림", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.Margin = new System.Windows.Forms.Padding(6);
            this.Name = "Form1";
            this.Text = "Wafer 등록기";
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).EndInit();
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.ListBox lbox_wafer;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.ComboBox cbox_company;
        private System.Windows.Forms.Button btn_com_add;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox tbox_name;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.RadioButton rb_111;
        private System.Windows.Forms.RadioButton rb_110;
        private System.Windows.Forms.RadioButton rb_100;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.NumericUpDown nud_radius;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.RadioButton rb_n;
        private System.Windows.Forms.RadioButton rb_p;
        private System.Windows.Forms.Button btn_add;
        private System.Windows.Forms.Button btn_remove;
    }
}

5. 이벤트 핸들러 구현

5.1 btn_com_add의 Click 이벤트 핸들러

콤보 박스에 입력한 내용 혹은 현재 보이는 내용은 Text 속성을 통해 확인할 수 있습니다.

콤보 박스에 항목을 추가할 때는 Items 컬렉션에 Add 메서드를 호출합니다.

        private void btn_com_add_Click(object sender, EventArgs e)
        {
            string company = cbox_company.Text;
            cbox_company.Items.Add(company);
            cbox_company.Text = "";
        }

5.2 btn_add의 Click 이벤트 핸들러

생성할 Wafer 개체의 속성 값을 얻어옵니다.

회사 이름은 cbox_company의 Text 속성으로 얻어옵니다.

제품 이름은 tbox_name의 Text 속성으로 얻어옵니다.

방향은 관련 RadioButton의 체크 상태에 따라 다릅니다. 이를 얻어오는 메서드(GetWDirection)를 별도로 만들어서 얻어옵시다.

반경은 nud_radius의 Value 속성으로 얻어옵니다. 주의할 점은 Value 속성의 타입은 decimal인데 Wafer의 radius는 double 형식이므로 형식 변환을 요구합니다.

타입은 두 가지 중에 하나이므로 rb_p의 Checked 상태로 확인할 수 있습니다.

이렇게 얻어온 값으로 Wafer 개체를 생성하여 lbox_wafer의 Items 컬렉션에 추가합니다.

컨트롤의 상태를 다음 Wafer를 입력하기 쉽게 리셋합니다. 이 부분도 별도의 메서드(ResetControl)로 만들어서 수행합니다.

        private void btn_add_Click(object sender, EventArgs e)
        {
            string company = cbox_company.Text;
            string pname = tbox_name.Text;
            WDirection wd = GetWDirection();
            double radius = (double)nud_radius.Value;
            bool ptype = rb_p.Checked;
            Wafer wafer = new Wafer(company, pname, wd, radius, ptype);
            lbox_wafer.Items.Add(wafer);
            ResetControl();
        }

GetWDirection 메서드는 방향 관련 RadioButton의 Checked 속성 값에 따라 반환 값을 결정합니다.

        private WDirection GetWDirection()
        {
            if(rb_100.Checked)
            {
                return WDirection.WD_100;
            }
            if(rb_110.Checked)
            {
                return WDirection.WD_110;
            }
            return WDirection.WD_111;
        }

ResetControl 메서드 각 컨트롤의 상태를 적절할 값으로 설정합니다. 

        private void ResetControl()
        {
            cbox_company.Text = "";
            tbox_name.Text = "";
            rb_100.Checked = true;
            nud_radius.Value = 0;
            rb_p.Checked = true;
        }

5.3 btn_remove의 Click 이벤트 핸들러

lbox_wafer의 선택 항목 인덱스를 얻어옵니다.

lbox_wafer의 Items 컨트롤에서 해당 인덱스 요소를 제거합니다.

        private void btn_remove_Click(object sender, EventArgs e)
        {
            int index = lbox_wafer.SelectedIndex;
            lbox_wafer.Items.RemoveAt(index);
        }  

5.4 lbox_wafer의 선택 항목 변경 이벤트 핸들러

선택 항목이 없다면 btn_remove를 비활성화 상태로 설정하고 각 컨트롤 상태를 리셋합니다.

선택 항목이 있다면 btn_remove를 활성화 상태로 설정하고 선택 항목의 아이템을 Wafer 형식 개체로 참조합니다.

wafer 개체의 값으로 컨트롤의 상태를 설정합니다. 이 부분은 별도의 메서드로 정의합시다.

        private void lbox_wafer_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(lbox_wafer.SelectedIndex == -1)//선택 항목이 없다면
            {
                btn_remove.Enabled = false;
                ResetControl();
                return;
            }
            btn_remove.Enabled = true;
            Wafer wafer = lbox_wafer.SelectedItem as Wafer;
            SetControlWafer(wafer);
        }

회사 이름으로 cbot_company의 Text 속성을 설정합니다.

제품 이름으로 tbox_name의 Text 속성을 설정합니다.

wafer의 방향을 설정하는 부분은 별도의 메서드를 만들어서 사용할게요.

반경으로 nud_radius의 Value 속성을 설정합니다. 형식이 다르므로 decimal로 명시적 형변환합니다.

wafer 타입 설정도 별도의 메서드를 만들어서 사용할게요.

        private void SetControlWafer(Wafer wafer)
        {
            cbox_company.Text = wafer.Company;
            tbox_name.Text = wafer.Name;
            SetWDir(wafer.WDir);
            nud_radius.Value = (decimal)wafer.Radius;
            SetType(wafer.PType);
        }

방향과 타입을 결정하는 메서드를 정의합시다.

        private void SetType(bool pt)
        {
            if(pt)
            {
                rb_p.Checked = true;
            }
            else
            {
                rb_n.Checked = true;
            }
        }

        private void SetWDir(WDirection wd)
        {
            switch (wd)
            {
                case WDirection.WD_100: rb_100.Checked = true; break;
                case WDirection.WD_110: rb_110.Checked = true; break;
                case WDirection.WD_111: rb_111.Checked = true; break;
            }
        }

6. Form1.cs 코드

using System;
using System.Windows.Forms;

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



        private void btn_com_add_Click(object sender, EventArgs e)
        {
            string company = cbox_company.Text;
            cbox_company.Items.Add(company);
            cbox_company.Text = "";
        }

        private void btn_add_Click(object sender, EventArgs e)
        {
            string company = cbox_company.Text;
            string pname = tbox_name.Text;
            WDirection wd = GetWDirection();
            double radius = (double)nud_radius.Value;
            bool ptype = rb_p.Checked;
            Wafer wafer = new Wafer(company, pname, wd, radius, ptype);
            lbox_wafer.Items.Add(wafer);
            ResetControl();
        }

        private void ResetControl()
        {
            cbox_company.Text = "";
            tbox_name.Text = "";
            rb_100.Checked = true;
            nud_radius.Value = 0;
            rb_p.Checked = true;
        }

        private WDirection GetWDirection()
        {
            if(rb_100.Checked)
            {
                return WDirection.WD_100;
            }
            if(rb_110.Checked)
            {
                return WDirection.WD_110;
            }
            return WDirection.WD_111;
        }

        private void btn_remove_Click(object sender, EventArgs e)
        {
            int index = lbox_wafer.SelectedIndex;
            lbox_wafer.Items.RemoveAt(index);
        }

        private void lbox_wafer_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(lbox_wafer.SelectedIndex == -1)//선택 항목이 없다면
            {
                btn_remove.Enabled = false;
                ResetControl();
                return;
            }
            btn_remove.Enabled = true;
            Wafer wafer = lbox_wafer.SelectedItem as Wafer;
            SetControlWafer(wafer);
        }

        private void SetControlWafer(Wafer wafer)
        {
            cbox_company.Text = wafer.Company;
            tbox_name.Text = wafer.Name;
            SetWDir(wafer.WDir);
            nud_radius.Value = (decimal)wafer.Radius;
            SetType(wafer.PType);
        }

        private void SetType(bool pt)
        {
            if(pt)
            {
                rb_p.Checked = true;
            }
            else
            {
                rb_n.Checked = true;
            }
        }

        private void SetWDir(WDirection wd)
        {
            switch(wd)
            {
                case WDirection.WD_100: rb_100.Checked = true; break;
                case WDirection.WD_110: rb_110.Checked = true; break;
                case WDirection.WD_111: rb_111.Checked = true; break;
            }
        }
    }
}

 

반응형