728x90
반응형
728x170
▶ MainForm.cs
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 상태 추가하기 대리자 - AddStatusDelegate(text)
/// <summary>
/// 상태 추가하기 대리자
/// </summary>
/// <param name="text">텍스트</param>
private delegate void AddStatusDelegate(string text);
#endregion
#region 값 그리기 대리자 - PlotValueDelegate(previousY, newY)
/// <summary>
/// 값 그리기 대리자
/// </summary>
/// <param name="previousY">이전 Y 값</param>
/// <param name="newY">신규 Y 값</param>
private delegate void PlotValueDelegate(int previousY, int newY);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 그리드 단계
/// </summary>
private const int GRID_STEP = 40;
/// <summary>
/// Y 중간값
/// </summary>
private int yMiddle;
/// <summary>
/// Y 값
/// </summary>
private int yValue;
/// <summary>
/// 그래프 스레드
/// </summary>
private Thread graphThread;
/// <summary>
/// 난수 발생기
/// </summary>
private Random random = new Random();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
#region 이벤트를 설정한다.
Load += Form_Load;
this.graphButton.Click += graphButton_Click;
this.timer.Tick += timer_Tick;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Load(object sender, EventArgs e)
{
this.yMiddle = this.graphPictureBox.ClientSize.Height / 2;
this.yValue = this.yMiddle;
int bitmapWidth = this.graphPictureBox.ClientSize.Width;
int bitmapHeight = this.graphPictureBox.ClientSize.Height;
Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.Blue);
for(int i = this.yMiddle; i <= this.graphPictureBox.ClientSize.Height; i += GRID_STEP)
{
graphics.DrawLine(Pens.LightBlue, 0, i, bitmapWidth - 1, i);
}
for(int i = this.yMiddle; i >= 0; i -= GRID_STEP)
{
graphics.DrawLine(Pens.LightBlue, 0, i, bitmapWidth - 1, i);
}
this.graphPictureBox.Image = bitmap;
}
#endregion
#region 그래프 버튼 클릭시 처리하기 - graphButton_Click(sender, e)
/// <summary>
/// 그래프 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void graphButton_Click(object sender, EventArgs e)
{
if(this.graphThread == null)
{
AddStatus("스레드를 시작합니다.");
this.graphThread = new Thread(DrawGraph);
this.graphThread.Priority = ThreadPriority.BelowNormal;
this.graphThread.IsBackground = true;
this.graphThread.Start();
AddStatus("스레드가 시작되었습니다.");
this.graphButton.Text = "중단";
}
else
{
AddStatus("스레드를 중단합니다.");
this.graphThread.Abort();
this.graphThread = null;
AddStatus("스레드가 중단되었습니다.");
this.graphButton.Text = "그래프";
}
}
#endregion
#region 타이머 틱 처리하기 - timer_Tick(sender, e)
/// <summary>
/// 타이머 틱 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void timer_Tick(object sender, EventArgs e)
{
this.timeLabel.Text = DateTime.Now.ToString("T");
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 상태 추가하기 - AddStatus(text)
/// <summary>
/// 상태 추가하기
/// </summary>
/// <param name="text">텍스트</param>
private void AddStatus(string text)
{
if(InvokeRequired)
{
object[] argumentArray = new object[] { text };
AddStatusDelegate addStatusDelegate = AddStatus;
Invoke(addStatusDelegate, argumentArray);
return;
}
this.statusTextBox.AppendText("\r\n" + text);
this.statusTextBox.Select(statusTextBox.Text.Length, 0);
this.statusTextBox.ScrollToCaret();
}
#endregion
#region Y 값 설정하기 - SetYValue()
/// <summary>
/// Y 값 설정하기
/// </summary>
private void SetYValue()
{
DateTime stopTime = DateTime.Now.AddMilliseconds(20);
while(DateTime.Now < stopTime)
{
}
this.yValue += this.random.Next(-4, 5);
if(this.yValue < 0)
{
this.yValue = 0;
}
if(this.yValue >= this.graphPictureBox.ClientSize.Height - 1)
{
this.yValue = graphPictureBox.ClientSize.Height - 1;
}
}
#endregion
#region 값 그리기 - PlotValue(previousY, newY)
/// <summary>
/// 값 그리기
/// </summary>
/// <param name="previousY">이전 Y 값</param>
/// <param name="newY">신규 Y 값</param>
private void PlotValue(int previousY, int newY)
{
if(InvokeRequired)
{
object[] argumentArray = new object[] { previousY, newY };
PlotValueDelegate plotValueDelegate = PlotValue;
Invoke(plotValueDelegate, argumentArray);
return;
}
int bitmapWidth = this.graphPictureBox.ClientSize.Width;
int bitmapHeight = this.graphPictureBox.ClientSize.Height;
Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.DrawImage(this.graphPictureBox.Image, -1, 0);
graphics.DrawLine(Pens.Blue, bitmapWidth - 1, 0, bitmapWidth - 1, bitmapHeight - 1);
for(int i = this.yMiddle; i <= graphPictureBox.ClientSize.Height; i += GRID_STEP)
{
graphics.DrawLine(Pens.LightBlue, bitmapWidth - 2, i, bitmapWidth - 1, i);
}
for(int i = this.yMiddle; i >= 0; i -= GRID_STEP)
{
graphics.DrawLine(Pens.LightBlue, bitmapWidth - 2, i, bitmapWidth - 1, i);
}
graphics.DrawLine(Pens.White, bitmapWidth - 2, previousY, bitmapWidth - 1, newY);
this.graphPictureBox.Image = bitmap;
this.graphPictureBox.Refresh();
graphics.Dispose();
}
#endregion
#region 그래프 그리기 - DrawGraph()
/// <summary>
/// 그래프 그리기
/// </summary>
private void DrawGraph()
{
try
{
int y = this.yValue;
for(;;)
{
SetYValue();
PlotValue(y, this.yValue);
y = this.yValue;
}
}
catch(Exception exception)
{
AddStatus("[스레드] " + exception.Message);
}
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 국화 곡선(Chrysanthemum Curve) 그리기 (0) | 2018.12.22 |
---|---|
[C#/WINFORM] PictureBox 클래스 : 더블 버퍼링 사용하기 (0) | 2018.12.22 |
[C#/WINFORM] 에피트로코이드(Epitrochoid) 그리기 (애니메이션) (0) | 2018.12.22 |
[C#/WINFORM] 에피트로코이드(Epitrochoid) 그리기 (0) | 2018.12.22 |
[C#/WINFORM] TabControl 클래스 : 사용자 정의 그리기 (0) | 2018.12.22 |
[C#/WINFORM] 타원과 타원 교차점 구하기 (0) | 2018.12.21 |
[C#/WINFORM] PictureBox 클래스 : SizeMode 속성에 따라 이미지 구하기 (0) | 2018.12.19 |
[C#/WINFORM] 다항식 최소 제곱법(Polynomial Least Squares Method) 사용하기 (0) | 2018.12.19 |
[C#/WINFORM] 선형 최소 제곱법(Linear Least Squares Method) 사용하기 (0) | 2018.12.19 |
[C#/WINFORM] ColorDialog 클래스 : 커스텀 색상 사용하기 (0) | 2018.12.19 |
댓글을 달아 주세요