[C#, Widows Form 실습] Wafer 등록기 - 반도체 제어시스템 시뮬
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;
}
}
}
}