1. 앞에서 작성하였던 RCMachine.cs와 CotingEventArgs.cs 파일로 구성한 클래스 라이브러리를 만듭니다.
2. Windows Forms 앱(.NET Framework) 프로젝트("RCManchine_공장_예광탄")를 생성합니다.
3. 생성한 프로젝트에 사용자 정의 컨트롤(Windows Forms)을 추가합니다. 파일명: RCMachineControl.cs
4. DPanel 클래스를 추가합니다.
더블 버퍼링이 가능한 패널을 정의한 클래스입니다.
DPanel.cs
namespace RCManchine_공장_예광탄
{
public class DPanel:System.Windows.Forms.Panel
{
public DPanel()
{
SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer |
System.Windows.Forms.ControlStyles.UserPaint |
System.Windows.Forms.ControlStyles.AllPaintingInWmPaint
, true);
UpdateStyles();
}
}
}
5. RCMachineControl에 자식 컨트롤을 배치합니다.
pn으로 시작하는 컨트롤은 Panel로 배치하세요.
6. RCMachineControlDesigner.cs 파일에 가서 InitializeComponent 메서드의 앞쪽 코드 중에 Panel 개체 생성 코드를 DPanel 생성 코드로 수정합니다.
RCMachineControlDesigner.cs
namespace RCManchine_공장_예광탄
{
partial class RCMachineControl
{
/// <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 구성 요소 디자이너에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.lb_liq = new System.Windows.Forms.Label();
this.lb_avail = new System.Windows.Forms.Label();
this.lb_source = new System.Windows.Forms.Label();
this.lb_radius = new System.Windows.Forms.Label();
this.lb_area = new System.Windows.Forms.Label();
this.lb_speed = new System.Windows.Forms.Label();
this.lb_product = new System.Windows.Forms.Label();
this.pn_source = new DPanel();
this.pn_record = new DPanel();
this.pn_product = new DPanel();
this.pn_liq = new DPanel();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(16, 23);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(80, 21);
this.label1.TabIndex = 0;
this.label1.Text = "코딩액:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(267, 23);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(80, 21);
this.label2.TabIndex = 1;
this.label2.Text = "남은양:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(37, 85);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(59, 21);
this.label3.TabIndex = 2;
this.label3.Text = "소스:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(369, 76);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(129, 21);
this.label4.TabIndex = 3;
this.label4.Text = "투입구 반경:";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(455, 165);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(59, 21);
this.label5.TabIndex = 4;
this.label5.Text = "면적:";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(271, 243);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(101, 21);
this.label6.TabIndex = 5;
this.label6.Text = "회전속도:";
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(20, 289);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(199, 21);
this.label7.TabIndex = 6;
this.label7.Text = "코팅한 레코드 개수:";
//
// lb_liq
//
this.lb_liq.AutoSize = true;
this.lb_liq.Location = new System.Drawing.Point(102, 23);
this.lb_liq.Name = "lb_liq";
this.lb_liq.Size = new System.Drawing.Size(51, 21);
this.lb_liq.TabIndex = 7;
this.lb_liq.Text = "lb_liq";
//
// lb_avail
//
this.lb_avail.AutoSize = true;
this.lb_avail.Location = new System.Drawing.Point(353, 23);
this.lb_avail.Name = "lb_avail";
this.lb_avail.Size = new System.Drawing.Size(70, 21);
this.lb_avail.TabIndex = 8;
this.lb_avail.Text = "lb_avail";
//
// lb_source
//
this.lb_source.AutoSize = true;
this.lb_source.Location = new System.Drawing.Point(106, 85);
this.lb_source.Name = "lb_source";
this.lb_source.Size = new System.Drawing.Size(92, 21);
this.lb_source.TabIndex = 9;
this.lb_source.Text = "lb_source";
//
// lb_radius
//
this.lb_radius.AutoSize = true;
this.lb_radius.Location = new System.Drawing.Point(504, 76);
this.lb_radius.Name = "lb_radius";
this.lb_radius.Size = new System.Drawing.Size(82, 21);
this.lb_radius.TabIndex = 10;
this.lb_radius.Text = "lb_radius";
//
// lb_area
//
this.lb_area.AutoSize = true;
this.lb_area.Location = new System.Drawing.Point(520, 165);
this.lb_area.Name = "lb_area";
this.lb_area.Size = new System.Drawing.Size(70, 21);
this.lb_area.TabIndex = 11;
this.lb_area.Text = "lb_area";
//
// lb_speed
//
this.lb_speed.AutoSize = true;
this.lb_speed.Location = new System.Drawing.Point(379, 243);
this.lb_speed.Name = "lb_speed";
this.lb_speed.Size = new System.Drawing.Size(87, 21);
this.lb_speed.TabIndex = 12;
this.lb_speed.Text = "lb_speed";
//
// lb_product
//
this.lb_product.AutoSize = true;
this.lb_product.Location = new System.Drawing.Point(225, 289);
this.lb_product.Name = "lb_product";
this.lb_product.Size = new System.Drawing.Size(98, 21);
this.lb_product.TabIndex = 13;
this.lb_product.Text = "lb_product";
//
// pn_source
//
this.pn_source.BackColor = System.Drawing.Color.Maroon;
this.pn_source.Location = new System.Drawing.Point(20, 121);
this.pn_source.Name = "pn_source";
this.pn_source.Size = new System.Drawing.Size(184, 143);
this.pn_source.TabIndex = 14;
this.pn_source.Paint += new System.Windows.Forms.PaintEventHandler(this.pn_source_Paint);
//
// pn_record
//
this.pn_record.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
this.pn_record.Location = new System.Drawing.Point(271, 111);
this.pn_record.Name = "pn_record";
this.pn_record.Size = new System.Drawing.Size(178, 129);
this.pn_record.TabIndex = 15;
this.pn_record.Paint += new System.Windows.Forms.PaintEventHandler(this.pn_record_Paint);
//
// pn_product
//
this.pn_product.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.pn_product.Location = new System.Drawing.Point(357, 289);
this.pn_product.Name = "pn_product";
this.pn_product.Size = new System.Drawing.Size(200, 151);
this.pn_product.TabIndex = 16;
this.pn_product.Paint += new System.Windows.Forms.PaintEventHandler(this.pn_product_Paint);
//
// pn_liq
//
this.pn_liq.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.pn_liq.Location = new System.Drawing.Point(339, 76);
this.pn_liq.Name = "pn_liq";
this.pn_liq.Size = new System.Drawing.Size(24, 24);
this.pn_liq.TabIndex = 17;
this.pn_liq.Paint += new System.Windows.Forms.PaintEventHandler(this.pn_liq_Paint);
//
// RCMachineControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.pn_liq);
this.Controls.Add(this.pn_product);
this.Controls.Add(this.pn_record);
this.Controls.Add(this.pn_source);
this.Controls.Add(this.lb_product);
this.Controls.Add(this.lb_speed);
this.Controls.Add(this.lb_area);
this.Controls.Add(this.lb_radius);
this.Controls.Add(this.lb_source);
this.Controls.Add(this.lb_avail);
this.Controls.Add(this.lb_liq);
this.Controls.Add(this.label7);
this.Controls.Add(this.label6);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.Margin = new System.Windows.Forms.Padding(5);
this.Name = "RCMachineControl";
this.Size = new System.Drawing.Size(597, 456);
this.Load += new System.EventHandler(this.RCMachineControl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label lb_liq;
private System.Windows.Forms.Label lb_avail;
private System.Windows.Forms.Label lb_source;
private System.Windows.Forms.Label lb_radius;
private System.Windows.Forms.Label lb_area;
private System.Windows.Forms.Label lb_speed;
private System.Windows.Forms.Label lb_product;
private System.Windows.Forms.Panel pn_source;
private System.Windows.Forms.Panel pn_record;
private System.Windows.Forms.Panel pn_product;
private System.Windows.Forms.Panel pn_liq;
}
}
7. RCMachineControl.cs 에 코드를 작성합니다.
- RCMachine 형식 개체를 참조하는 멤버 필드와 이를 설정하고 가져오기할 속성을 정의합니다.
- RCMachine 개에의 상태에 따라 컨트롤 속성을 변경할 수 있게 구현합니다.
RCMachineConrol.cs
using RCMachineControlLib;
using System.Drawing;
using System.Windows.Forms;
using 콘솔_예광탄;
namespace RCManchine_공장_예광탄
{
public partial class RCMachineControl : UserControl
{
public event EndCotingEventHandler OnEnd;
public RCMachineControl()
{
InitializeComponent();
}
RCMachine rcmachine;
public RCMachine RCMachine
{
get
{
return rcmachine;
}
set
{
rcmachine = value;
if(rcmachine != null)
{
SetVisualProperty();
rcmachine.OnCoting += Rcmachine_OnCoting;
Invalidate();
}
}
}
int tobe;
int acnt;
private void Rcmachine_OnCoting(object sender, CotingEventArgs e)
{
SetVisualProperty();
tobe = e.Tobe;
acnt = e.AvailCnt;
if((rcmachine.IsStart==false)&&(OnEnd!=null))
{
OnEnd(this, new EndCotingEventArgs(e.ProductCnt));
}
}
public void SetArea(decimal value)
{
rcmachine.RArea = (int)value;
lb_area.Text = value.ToString();
pn_record.Invalidate();
}
public void SetSpeed(decimal value)
{
rcmachine.SpinSpeed = (int)value;
lb_speed.Text = value.ToString();
}
public void AddSource(decimal value)
{
rcmachine.SourceCnt += (int)value;
lb_source.Text = rcmachine.SourceCnt.ToString();
pn_source.Invalidate();
}
public void AddLiq(decimal value)
{
rcmachine.CoatingLiq += (int)value;
lb_liq.Text = rcmachine.CoatingLiq.ToString();
pn_liq.Invalidate();
}
public void SetRadius(decimal value)
{
rcmachine.CRadius = (int)value;
lb_radius.Text = value.ToString();
}
//크로스 스레드 문제가 발생한 메서드와 원형이 같은 대리자를 정의
delegate void SetVisualPropertyDele();
private void SetVisualProperty()
{
if (rcmachine == null)
{
return;
}
if (this.InvokeRequired)//크로스 스레드 문제가 발생했다면
{
//대리자 개체에 메소드 자신을 설정
SetVisualPropertyDele dele = SetVisualProperty;
//Form 컨트롤의 Invoke 메서드에 대리자를 전달
// .NET 에서 Form을 소유한 스레드가 해당 메서드를 수행함을 보장
this.Invoke(dele);
}
else
{
lb_area.Text = rcmachine.RArea.ToString();
lb_avail.Text = "0";
lb_source.Text = rcmachine.SourceCnt.ToString();
lb_speed.Text = rcmachine.SpinSpeed.ToString();
lb_liq.Text = rcmachine.CoatingLiq.ToString();
lb_product.Text = rcmachine.ProductCnt.ToString();
lb_radius.Text = rcmachine.CRadius.ToString();
lb_avail.Text = acnt.ToString();
Invalidate(true);
}
}
private void pn_source_Paint(object sender, PaintEventArgs e)
{
if (rcmachine == null)
{
return;
}
Graphics graphics = e.Graphics;
for (int i = 0; i < rcmachine.SourceCnt; i++)
{
Rectangle rect = new Rectangle(4, i * 10, pn_source.Width - 8, 9);
graphics.DrawRectangle(Pens.White, rect);
}
}
private void pn_record_Paint(object sender, PaintEventArgs e)
{
if (rcmachine == null)
{
return;
}
Graphics graphics = e.Graphics;
for (int i = 0; i < rcmachine.RArea; i++)
{
Rectangle rect = new Rectangle((i/10)*10, (i%10) * 10, pn_record.Width/20, 9);
if (i > rcmachine.RArea - tobe)
{
graphics.DrawRectangle(Pens.White, rect);
}
else
{
graphics.DrawRectangle(Pens.Gold, rect);
}
}
}
private void pn_liq_Paint(object sender, PaintEventArgs e)
{
if(rcmachine == null)
{
return;
}
Graphics graphics = e.Graphics;
int i;
for (i = 0; i < rcmachine.CoatingLiq; i++)
{
Rectangle rect = new Rectangle(0, i * 6, pn_liq.Width, 5);
graphics.DrawRectangle(Pens.Red, rect);
graphics.FillRectangle(Brushes.Gold, rect);
}
int awidth = (pn_liq.Width * acnt) / rcmachine.MAXACNT;
Rectangle rect1 = new Rectangle(0, i * 6, awidth, 5);
graphics.DrawRectangle(Pens.Red, rect1);
graphics.FillRectangle(Brushes.Gold, rect1);
Rectangle rect2 = new Rectangle(awidth, i * 6, pn_liq.Width- awidth, 5);
graphics.DrawRectangle(Pens.Red, rect2);
}
private void pn_product_Paint(object sender, PaintEventArgs e)
{
if (rcmachine == null)
{
return;
}
Graphics graphics = e.Graphics;
for(int i = 0; i<rcmachine.ProductCnt;i++)
{
Rectangle rect = new Rectangle(4, i * 10, pn_product.Width-8, 9);
graphics.DrawRectangle(Pens.Gold, rect);
}
}
private void RCMachineControl_Load(object sender, System.EventArgs e)
{
}
}
}
8. Form1.cs 에 RCMachineControl을 배치하고 컨트롤 이름을 rccon이라 지정합니다.
Form1에 Load이벤트 핸들러를 등록하여 RCMachine 개체 생성 및 rccon에 생성한 개체를 설정하는 코드를 추가합니다.
Form1.cs
using System;
using System.Windows.Forms;
using 콘솔_예광탄;
namespace RCManchine_공장_예광탄
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
RCMachine rc = new RCMachine();
rc.RArea = 100;
rc.CoatingLiq = 2;
rc.CRadius = 3;
rc.SpinSpeed = 100;
rc.SourceCnt = 10;
rccon.RCMachine = rc;
rc.Start();
}
}
}
'언어 자료구조 알고리즘 > 프로그래밍 실습' 카테고리의 다른 글
[C# 실습,설비 컨트롤 예광탄] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
---|---|
[C# 실습,예광탄] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습, 시나리오] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습] 레코드 코팅 - 기계(서버)와 제어기(클라이언트) (0) | 2020.10.07 |
[C# 실습] 레코드 코팅 - 기계 구현(Windows Forms) (0) | 2020.10.07 |
[C# 실습] 레코드 코팅 - 더블 버퍼링 가능한 Panel 정의하기 (0) | 2020.10.06 |
[C# 실습, 예광탄 소스] 레코드 코팅 (0) | 2020.10.06 |
[C# 실습 시나리오] 레코드 코팅 - 반도체 장비 및 제어시스템 개발자 양성 과정 (0) | 2020.10.06 |
[C# 실습] 반도체 장비 관리 프로그램 - 3. 상세 구현 (0) | 2020.09.22 |
[C# 실습] 반도체 장비 관리 프로그램 - 2. 프로토 타이핑 (0) | 2020.09.21 |