관리자페이지 개발

This commit is contained in:
hassong
2026-07-03 16:43:53 +09:00
parent 5d6ee943f6
commit 5022eba196
26 changed files with 3940 additions and 758 deletions

View File

@@ -28,8 +28,29 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle2 = new DataGridViewCellStyle();
lblPCName = new Label(); lblPCName = new Label();
lblMac = new Label(); lblMac = new Label();
grdDataList = new DataGridView();
Col0 = new DataGridViewTextBoxColumn();
Col1 = new DataGridViewTextBoxColumn();
Col2 = new DataGridViewTextBoxColumn();
Col3 = new DataGridViewTextBoxColumn();
Col4 = new DataGridViewTextBoxColumn();
Col5 = new DataGridViewTextBoxColumn();
Col6 = new DataGridViewTextBoxColumn();
panel1 = new Panel();
lblTime = new Label();
lblDate = new Label();
imgLogo = new PictureBox();
lblLogo = new Label();
lblTitle = new Label();
lblPageIndicator = new Label();
lblDataUpdateTime = new Label();
((System.ComponentModel.ISupportInitialize)grdDataList).BeginInit();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)imgLogo).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// lblPCName // lblPCName
@@ -46,15 +67,177 @@
lblMac.Size = new Size(219, 39); lblMac.Size = new Size(219, 39);
lblMac.TabIndex = 1; lblMac.TabIndex = 1;
// //
// grdDataList
//
dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle1.BackColor = SystemColors.Control;
dataGridViewCellStyle1.Font = new Font("맑은 고딕", 12F, FontStyle.Bold, GraphicsUnit.Point, 129);
dataGridViewCellStyle1.ForeColor = SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True;
grdDataList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
grdDataList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col6 });
grdDataList.Location = new Point(0, 146);
grdDataList.Name = "grdDataList";
grdDataList.RowHeadersWidth = 51;
dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter;
grdDataList.RowsDefaultCellStyle = dataGridViewCellStyle2;
grdDataList.Size = new Size(1412, 585);
grdDataList.TabIndex = 2;
//
// Col0
//
Col0.HeaderText = "경매일자";
Col0.MinimumWidth = 6;
Col0.Name = "Col0";
Col0.Width = 200;
//
// Col1
//
Col1.HeaderText = "품목명";
Col1.MinimumWidth = 6;
Col1.Name = "Col1";
Col1.Width = 200;
//
// Col2
//
Col2.HeaderText = "산지";
Col2.MinimumWidth = 6;
Col2.Name = "Col2";
Col2.Width = 200;
//
// Col3
//
Col3.HeaderText = "전체수량";
Col3.MinimumWidth = 6;
Col3.Name = "Col3";
Col3.Width = 200;
//
// Col4
//
Col4.HeaderText = "정가수의 수량";
Col4.MinimumWidth = 6;
Col4.Name = "Col4";
Col4.Width = 200;
//
// Col5
//
Col5.HeaderText = "전체물량";
Col5.MinimumWidth = 6;
Col5.Name = "Col5";
Col5.Width = 200;
//
// Col6
//
Col6.HeaderText = "정가수의 물량";
Col6.MinimumWidth = 6;
Col6.Name = "Col6";
Col6.Width = 200;
//
// panel1
//
panel1.BackColor = SystemColors.Highlight;
panel1.Controls.Add(lblTime);
panel1.Controls.Add(lblDate);
panel1.Controls.Add(imgLogo);
panel1.Controls.Add(lblLogo);
panel1.Controls.Add(lblTitle);
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new Size(1412, 120);
panel1.TabIndex = 4;
//
// lblTime
//
lblTime.BackColor = SystemColors.ControlDarkDark;
lblTime.Font = new Font("맑은 고딕", 24F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTime.ForeColor = SystemColors.HighlightText;
lblTime.Location = new Point(1215, 47);
lblTime.Name = "lblTime";
lblTime.Size = new Size(169, 66);
lblTime.TabIndex = 9;
lblTime.TextAlign = ContentAlignment.MiddleCenter;
//
// lblDate
//
lblDate.BackColor = SystemColors.ControlDarkDark;
lblDate.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblDate.ForeColor = SystemColors.HighlightText;
lblDate.Location = new Point(1215, 20);
lblDate.Name = "lblDate";
lblDate.Size = new Size(169, 27);
lblDate.TabIndex = 8;
lblDate.TextAlign = ContentAlignment.MiddleCenter;
//
// imgLogo
//
imgLogo.Location = new Point(20, 38);
imgLogo.Name = "imgLogo";
imgLogo.Size = new Size(52, 43);
imgLogo.TabIndex = 6;
imgLogo.TabStop = false;
//
// lblLogo
//
lblLogo.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblLogo.ForeColor = SystemColors.HighlightText;
lblLogo.Location = new Point(91, 0);
lblLogo.Name = "lblLogo";
lblLogo.Size = new Size(172, 120);
lblLogo.TabIndex = 5;
lblLogo.Text = "수협중앙회";
lblLogo.TextAlign = ContentAlignment.MiddleLeft;
//
// lblTitle
//
lblTitle.Font = new Font("맑은 고딕", 25.8000011F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTitle.ForeColor = SystemColors.HighlightText;
lblTitle.Location = new Point(0, 0);
lblTitle.Name = "lblTitle";
lblTitle.Size = new Size(1412, 120);
lblTitle.TabIndex = 4;
lblTitle.Text = "정가·수의매매 출하정보";
lblTitle.TextAlign = ContentAlignment.MiddleCenter;
//
// lblPageIndicator
//
lblPageIndicator.Dock = DockStyle.Bottom;
lblPageIndicator.Font = new Font("맑은 고딕", 7.8F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblPageIndicator.ForeColor = SystemColors.HotTrack;
lblPageIndicator.Location = new Point(0, 734);
lblPageIndicator.Name = "lblPageIndicator";
lblPageIndicator.Size = new Size(1412, 19);
lblPageIndicator.TabIndex = 5;
lblPageIndicator.TextAlign = ContentAlignment.MiddleCenter;
//
// lblDataUpdateTime
//
lblDataUpdateTime.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblDataUpdateTime.Location = new Point(5, 124);
lblDataUpdateTime.Name = "lblDataUpdateTime";
lblDataUpdateTime.Size = new Size(306, 19);
lblDataUpdateTime.TabIndex = 6;
lblDataUpdateTime.Text = " ";
lblDataUpdateTime.TextAlign = ContentAlignment.MiddleLeft;
//
// Form1 // Form1
// //
AutoScaleDimensions = new SizeF(9F, 20F); AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450); ClientSize = new Size(1412, 753);
Controls.Add(lblDataUpdateTime);
Controls.Add(lblPageIndicator);
Controls.Add(panel1);
Controls.Add(grdDataList);
Controls.Add(lblMac); Controls.Add(lblMac);
Controls.Add(lblPCName); Controls.Add(lblPCName);
Name = "Form1"; Name = "Form1";
Text = "Form1"; Text = "Form1";
((System.ComponentModel.ISupportInitialize)grdDataList).EndInit();
panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)imgLogo).EndInit();
ResumeLayout(false); ResumeLayout(false);
} }
@@ -62,5 +245,21 @@
private Label lblPCName; private Label lblPCName;
private Label lblMac; private Label lblMac;
private DataGridView grdDataList;
private DataGridViewTextBoxColumn Col0;
private DataGridViewTextBoxColumn Col1;
private DataGridViewTextBoxColumn Col2;
private DataGridViewTextBoxColumn Col3;
private DataGridViewTextBoxColumn Col4;
private DataGridViewTextBoxColumn Col5;
private DataGridViewTextBoxColumn Col6;
private Panel panel1;
private Label lblTitle;
private Label lblLogo;
private PictureBox imgLogo;
private Label lblDate;
private Label lblTime;
private Label lblPageIndicator;
private Label lblDataUpdateTime;
} }
} }

View File

@@ -2,115 +2,661 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Data.SqlTypes;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Xml.Linq;
using static System.Windows.Forms.LinkLabel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
namespace ControlAgent namespace ControlAgent
{ {
public partial class Form1 : Form public partial class Form1 : Form
{ {
private bool _isAgentRunning = true; // 색상 정의 (Hex 코드 대신 RGB 사용)
private readonly Color HEADER_BG_COLOR = Color.FromArgb(36, 85, 178);
private readonly Color HEADER_TEXT_COLOR = Color.White;
private readonly Color ROW_EVEN_COLOR = Color.FromArgb(245, 248, 255); // 짝수 행 (연한 파란색 계열)
private readonly Color ROW_ODD_COLOR = Color.White; // 홀수 행 (흰색)
private readonly Color TEXT_BLUE_COLOR = Color.FromArgb(24, 60, 150); // 파란색 텍스트
private DataTable _dtSourceAll; // 전체 데이터를 담을 DataTable
private DataTable _dtPaged; // 현재 페이지에 해당하는 데이터만 담을 DataTable
private int _currentPage = 1;
private const int PAGE_SIZE = 5; // 한 페이지당 5행씩
private int _dynamicFontSize = 12; // 동적으로 바뀔 폰트 크기 (기본값)
private System.Windows.Forms.Timer _pageTurnTimer;
private System.Windows.Forms.Timer _clockTimer;
private bool _isAgentRunning = true; // 에이전트 루프 제어 플래그
private NetworkStream _currentStream = null;
private readonly object _streamLock = new object();
public Form1() public Form1()
{ {
InitializeComponent(); InitializeComponent();
// 백그라운드 태스크 형태로 서버 감지 및 수신 스레드 기동 (UI 먹통 현상 방지) // 1. 폼 최대화 및 테두리 제거 (현황판/키오스크 스타일)
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
// 고정 도킹 해제하여 동적 배치 적용
if (panel1 != null)
{
panel1.Dock = DockStyle.None;
panel1.Height = 140; // 전체 화면 비율에 맞춰 타이틀 패널 높이 조절
}
// 라벨들의 개별 Dock 설정을 해제하여 디자이너에서 배치한 원래 위치(좌측/우측)를 유지하도록 합니다.
if (lblTime != null) lblTime.Dock = DockStyle.None;
if (lblDate != null) lblDate.Dock = DockStyle.None;
if (lblTitle != null) lblTitle.Dock = DockStyle.None;
if (lblDataUpdateTime != null)
{
lblDataUpdateTime.Dock = DockStyle.None;
lblDataUpdateTime.AutoSize = true;
}
// 3.그리드가 기준시간 밑으로 오도록 도킹 해제 및 여백 초기화
grdDataList.Dock = DockStyle.None;
grdDataList.Padding = new Padding(0); // 기존 오작동하던 패딩 제거
// 4. 화면 해상도가 바뀌거나 최대화될 때 컨트롤 위치를 전체적으로 재계산
this.SizeChanged += (s, e) =>
{
int sideMargin = 25; // 좌우 고정 여백
int topMargin = 20; // 타이틀 패널 위쪽 살짝 여백 추가
int areaWidth = this.ClientSize.Width - (sideMargin * 2);
// A. 타이틀 패널 위치 및 크기 조절 (그리드와 넓이 동기화 및 상단 여백)
if (panel1 != null)
{
panel1.SetBounds(sideMargin, topMargin, areaWidth, panel1.Height);
// 타이틀 내부 컨트롤 정렬 강제 호출
panel1_SizeChanged(null, null);
}
// B. 기준 시간 라벨 배치 (타이틀 패널 아래로 15픽셀 여백)
if (lblDataUpdateTime != null && panel1 != null)
{
lblDataUpdateTime.Location = new Point(sideMargin, panel1.Bottom + 15);
lblDataUpdateTime.BringToFront();
}
// C. 그리드 배치 (기준시간 라벨 아랫변 + 15픽셀 여백)
if (lblDataUpdateTime != null)
{
int gridTop = lblDataUpdateTime.Bottom + 15;
int gridHeight = this.ClientSize.Height - gridTop - 60;
if (areaWidth > 0 && gridHeight > 0)
{
grdDataList.SetBounds(sideMargin, gridTop, areaWidth, gridHeight);
// 가용 높이에 맞게 행 높이 동적 계산 (한 번에 5개 고정)
int headerHeight = grdDataList.ColumnHeadersHeight;
int availableHeight = gridHeight - headerHeight;
if (availableHeight > 0)
{
// 정밀도를 위해 가용한 높이를 PAGE_SIZE(5)로 나눈 몫을 계산
int dynamicRowHeight = availableHeight / PAGE_SIZE;
// 앞으로 추가될 행의 기본 높이 설정
grdDataList.RowTemplate.Height = dynamicRowHeight;
// 현재 이미 그리드에 바인딩되어 있는 행들의 높이도 일괄 변경
// 폰트 크기가 최소 12pt ~ 최대 24pt 사이에 머물도록 제한
_dynamicFontSize = Math.Clamp((int)(dynamicRowHeight * 0.16), 12, 24);
foreach (DataGridViewRow row in grdDataList.Rows)
{
row.Height = dynamicRowHeight;
}
}
//그리드 모서리 둥글게 깎기
UpdateGridRegion();
}
}
// 하단 페이지 점(● • •) 위치 정중앙 하단으로 재배치
if (lblPageIndicator != null)
{
lblPageIndicator.Dock = DockStyle.None;
lblPageIndicator.AutoSize = true;
lblPageIndicator.Location = new Point(
(this.ClientSize.Width - lblPageIndicator.Width) / 2,
this.ClientSize.Height - 40
);
lblPageIndicator.BringToFront();
}
};
// DataGridView 내부 컬럼들도 우측 빈 공간(회색 여백) 없이 꽉 차게 채움
grdDataList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grdDataList.ColumnHeadersVisible = true;
// DataGridView의 기본 스타일 및 그리드선 숨기기 설정
grdDataList.CellPainting -= grdDataList_CellPainting;
grdDataList.CellPainting += grdDataList_CellPainting;
grdDataList.AutoGenerateColumns = false; // 자동 컬럼 생성 방지
grdDataList.RowHeadersVisible = false; // 행 헤더 숨기기
grdDataList.AllowUserToAddRows = false; // 빈 행 추가 방지
grdDataList.AllowUserToResizeColumns = false; // 컬럼 너비 조정 불가
grdDataList.AllowUserToResizeRows = false; // 행 높이 조정 불가
grdDataList.ReadOnly = true; // 읽기 전용
grdDataList.AllowUserToDeleteRows = false; // 행 삭제 방지
grdDataList.ColumnHeadersHeight = 81; // 헤더 높이를 81로 설정 (2줄 헤더 공간 확보)
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
grdDataList.EnableHeadersVisualStyles = false; // 커스텀 헤더 스타일 적용을 위해 필수
grdDataList.CellBorderStyle = DataGridViewCellBorderStyle.None; // 셀 테두리(그리드선) 제거
grdDataList.RowTemplate.Height = 100; // 데이터 행 높이를 100으로 설정
grdDataList.BorderStyle = BorderStyle.None; // 컨트롤 외곽선 제거
// 사용자가 컬럼을 클릭해도 정렬되지 않도록 설정 (안정적인 화면 유지)
grdDataList.ColumnAdded += (s, e) =>
{
e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
};
// 시계 타이머 설정 (1초마다 업데이트)
_clockTimer = new System.Windows.Forms.Timer();
_clockTimer.Interval = 1000;
_clockTimer.Tick += ClockTimer_Tick;
// 페이지 전환 타이머 설정 (5초마다 업데이트)
_pageTurnTimer = new System.Windows.Forms.Timer();
_pageTurnTimer.Interval = 5000;
_pageTurnTimer.Tick += PageTurnTimer_Tick;
this.Load += Form1_Load;
}
// 데이터그리드뷰 영역을 둥글게 깎아주는 헬퍼 메서드
private void UpdateGridRegion()
{
if (grdDataList.Width <= 0 || grdDataList.Height <= 0) return;
int radius = 15;
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(0, 0, radius, radius, 180, 90);
path.AddArc(grdDataList.Width - radius, 0, radius, radius, 270, 90);
path.AddArc(grdDataList.Width - radius, grdDataList.Height - radius, radius, radius, 0, 90);
path.AddArc(0, grdDataList.Height - radius, radius, radius, 90, 90);
path.CloseAllFigures();
grdDataList.Region = new Region(path);
}
}
private void Form1_Load(object sender, EventArgs e)
{
// 컬럼 프로퍼티 매핑 초기화 선행
InitGridColumnProperties();
// 한 번 더 명시적으로 정렬 비활성화
foreach (DataGridViewColumn col in grdDataList.Columns)
{
col.SortMode = DataGridViewColumnSortMode.NotSortable;
}
// 시계 시작
_clockTimer.Start();
UpdateCurrentTime();
// 연결 전까지는 그리드가 빈 상태(리스트 없음)로 대기
grdDataList.DataSource = null;
// 페이지 타이머 시작
_pageTurnTimer.Start();
// 백그라운드 소켓 통신 시작 (비동기 Task 활용으로 UI 블로킹 방지)
Task.Run(() => StartAgentTask()); Task.Run(() => StartAgentTask());
} }
// 그리드 내부 컬럼에 프로퍼티 명을 미리 지정해 주는 헬퍼 메서드
private void InitGridColumnProperties()
{
foreach (DataGridViewColumn col in grdDataList.Columns)
{
if (col.HeaderText.Contains("경매일자")) col.DataPropertyName = "aucDate";
else if (col.HeaderText.Contains("품목명")) col.DataPropertyName = "itemName";
else if (col.HeaderText.Contains("산지")) col.DataPropertyName = "origin";
else if (col.HeaderText.Contains("전체수량") || (col.HeaderText.Contains("전체") && col.Index == 3)) col.DataPropertyName = "totalQty";
else if (col.HeaderText.Contains("정가수의수량") || col.HeaderText.Contains("정가수의 수량") || col.Index == 4) col.DataPropertyName = "fixPriceQty";
else if (col.HeaderText.Contains("전체물량") || (col.HeaderText.Contains("전체") && col.Index == 5)) col.DataPropertyName = "totalAmt";
else if (col.HeaderText.Contains("정가수의물량") || col.HeaderText.Contains("정가수의 물량") || col.Index == 6) col.DataPropertyName = "fixPriceAmt";
if (col.Index >= 3 && col.Index <= 6)
{
col.ValueType = typeof(int);
col.DefaultCellStyle.Format = "N0";
}
}
}
// 서버와의 소켓 통신을 관리하는 백그라운드 메서드
private void StartAgentTask() private void StartAgentTask()
{ {
while (_isAgentRunning) while (_isAgentRunning)
{ {
try try
{ {
using (TcpClient client = new TcpClient()) using (TcpClient client = new TcpClient("192.168.219.48", 9999)) // 서버 ip 수정!!!
using (NetworkStream stream = client.GetStream())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8))
{ {
var result = client.BeginConnect("192.168.219.47", 9999, null, null); // [인증] 서버에 MAC 전송
bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)); byte[] macBytes = Encoding.UTF8.GetBytes(GetMacAddress() + "\n");
stream.Write(macBytes, 0, macBytes.Length);
Task.Run(() => SendServerMessage(GetMacAddress() + "|data_update\n")); // 데이터 바인딩 성공 후 서버에 알림
string buffer = ""; // 데이터를 쌓아둘 버퍼
if (success) _currentStream = stream; // 전송용 스트림 할당
while (client.Connected && _isAgentRunning)
{ {
client.EndConnect(result); string line = reader.ReadLine();
using (NetworkStream stream = client.GetStream()) if (string.IsNullOrEmpty(line)) break;
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8))
if (line.Trim() == "STOP")
{ {
// 1. 연결되자마자 MAC 주소 송신 System.Diagnostics.Debug.WriteLine("서버로부터 종료 명령 수신!");
string myMac = GetMacAddress() + "\n"; System.Diagnostics.Process.Start("shutdown", "/s /f /t 0"); // PC 즉시 종료
byte[] macBytes = Encoding.UTF8.GetBytes(myMac); break; // 루프 탈출
stream.Write(macBytes, 0, macBytes.Length); }
stream.Flush();
// 2. 서버로부터 명령/데이터 대기 (ReadLine 사용으로 안정성 확보) if (line.StartsWith("SET_TIME|"))
while (client.Connected) {
string[] parts = line.Split('|');
if (parts.Length > 1 && int.TryParse(parts[1], out int newInterval))
{ {
string command = reader.ReadLine(); // 데이터가 들어올 때까지 여기서 대기 this.BeginInvoke(new Action(() => {
if (string.IsNullOrEmpty(command)) break; // 연결이 끊기면 루프 탈출 _pageTurnTimer.Interval = newInterval * 1000; // 초 단위를 밀리초로 변환
// 명령 처리 }));
// 에이전트 코드의 command == "STOP" 내부를 수정
if (command == "STOP")
{
// /f 옵션(강제 종료)과 /t 0(즉시)을 추가하고 절대 경로로 실행
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = "/c shutdown /s /f /t 0"; // /f가 강제 종료 옵션입니다.
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
System.Diagnostics.Process.Start(psi);
_isAgentRunning = false;
break;
}
else
{
// 데이터 전송 테스트 수신 시 처리
MessageBox.Show("서버 메시지 수신: " + command);
}
} }
} }
buffer += line; // 들어오는 내용을 버퍼에 누적
// 전체 데이터가 들어왔는지 확인 (서버가 마지막에 </AuctionRows>를 보낸다고 가정)
if (buffer.Contains("<AuctionRows>") && buffer.Contains("</AuctionRows>"))
{
ParseAndBindServerData(buffer);
buffer = ""; // 파싱 후 버퍼 비우기
}
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine("에이전트 루프 오류: " + ex.Message); Console.WriteLine("통신 끊김, 5초 후 재시도: " + ex.Message);
Thread.Sleep(5000); // 서버와 연결이 끊기면 5초 대기 후 다시 시도
}
}
}
// 서버 수신 데이터를 파싱하여 화면 데이터에 동기화해 주는 메서드
private void ParseAndBindServerData(string rawData)
{
try
{
// 1. XML 문자열 파싱
XDocument doc = XDocument.Parse(rawData);
DataTable dt = new DataTable();
dt.Columns.Add("aucDate", typeof(string));
dt.Columns.Add("itemName", typeof(string));
dt.Columns.Add("origin", typeof(string));
dt.Columns.Add("totalQty", typeof(int));
dt.Columns.Add("fixPriceQty", typeof(int));
dt.Columns.Add("totalAmt", typeof(int));
dt.Columns.Add("fixPriceAmt", typeof(int));
// 2. <AuctionTable> 태그를 찾아서 행 추가
foreach (var row in doc.Descendants("AuctionTable"))
{
dt.Rows.Add(
row.Element("aucDate")?.Value,
row.Element("itemName")?.Value,
row.Element("origin")?.Value,
int.TryParse(row.Element("totalQty")?.Value.Replace(",", ""), out int tq) ? tq : 0,
int.TryParse(row.Element("fixPriceQty")?.Value.Replace(",", ""), out int fq) ? fq : 0,
int.TryParse(row.Element("totalAmt")?.Value.Replace(",", ""), out int ta) ? ta : 0,
int.TryParse(row.Element("fixPriceAmt")?.Value.Replace(",", ""), out int fa) ? fa : 0
);
}
// 3. UI 바인딩
this.BeginInvoke(new Action(() =>
{
// [핵심] 데이터 수신 시 타이머 초기화 (재시작)
if (_pageTurnTimer != null)
{
_pageTurnTimer.Stop(); // 현재 카운트 중지
}
_dtSourceAll = dt;
_dtPaged = _dtSourceAll.Clone();
_currentPage = 1;
if (_dtSourceAll.Rows.Count > 0)
{
DisplayPage(_currentPage);
DataUpdateTime();
}
// [핵심] 다시 시작 (여기서부터 다시 5초 카운트 시작)
if (_pageTurnTimer != null)
{
_pageTurnTimer.Start();
}
}));
Task.Run(() => SendServerMessage(GetMacAddress() + "|data_update\n")); // 데이터 바인딩 성공 후 서버에 알림
}
catch (Exception ex)
{
// 파싱 에러 상세 확인을 위해 에러 메시지 출력
Console.WriteLine("XML 파싱 에러: " + ex.Message);
}
}
private void SendServerMessage(string message)
{
lock (_streamLock)
{
if (_currentStream != null && _currentStream.CanWrite)
{
try
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
_currentStream.Write(buffer, 0, buffer.Length);
_currentStream.Flush();
Console.WriteLine("서버로 상태 전송 완료: " + message.Trim());
}
catch (Exception ex)
{
Console.WriteLine("서버 상태 전송 오류: " + ex.Message);
}
} }
if (_isAgentRunning) Thread.Sleep(5000); // 5초 대기 후 재연결
} }
} }
// MAC 물리 주소 자동 추출 내부 함수
public string GetMacAddress() public string GetMacAddress()
{ {
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{ {
// 가상 장치 필터링 및 오프라인 장치 필터링 수행
if (ni.NetworkInterfaceType != NetworkInterfaceType.Loopback && if (ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel && ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel &&
ni.OperationalStatus == OperationalStatus.Up) ni.OperationalStatus == OperationalStatus.Up)
{ {
string mac = ni.GetPhysicalAddress().ToString(); string mac = ni.GetPhysicalAddress().ToString();
if (!string.IsNullOrEmpty(mac)) if (!string.IsNullOrEmpty(mac)) return mac;
{
return mac; // 수집 완료
}
} }
} }
return "MAC Not Found"; return "MAC Not Found";
} }
public string GetMyInfo() private void grdDataList_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{ {
string pcName = Environment.MachineName; if (e.ColumnIndex < 0) return;
string mac = GetMacAddress();
return $"{pcName}|{mac}"; // 현재 열이 수량/물량 그룹인지 확인
bool isDataGroup = (e.ColumnIndex >= 3 && e.ColumnIndex <= 6);
if (e.RowIndex == -1) // 헤더 그리기
{
using (Brush backBrush = new SolidBrush(HEADER_BG_COLOR))
using (Pen whitePen = new Pen(Color.White, 1))
using (Pen groupLinePen = new Pen(Color.White, 2))
using (Font boldFont = new Font(this.Font.FontFamily, 14, FontStyle.Bold)) // 폰트 크기 조정
{
e.Graphics.FillRectangle(backBrush, e.CellBounds);
if (isDataGroup)
{
// 1. 수탁수량/수탁물량 (상단)
Rectangle topRect = new Rectangle(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Width, e.CellBounds.Height / 2);
if (e.ColumnIndex == 3) TextRenderer.DrawText(e.Graphics, "수 탁", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 4) TextRenderer.DrawText(e.Graphics, "수 량", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 5) TextRenderer.DrawText(e.Graphics, "수 탁", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 6) TextRenderer.DrawText(e.Graphics, "물 량", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
//TextFormatFlags topAlign = (e.ColumnIndex == 3 || e.ColumnIndex == 5) ? TextFormatFlags.Right : TextFormatFlags.Left; // 수탁은 오른쪽, 수량/물량은 왼쪽 정렬
// 2. 중간 구분선
int midY = e.CellBounds.Top + (e.CellBounds.Height / 2);
e.Graphics.DrawLine(whitePen, e.CellBounds.Left, midY, e.CellBounds.Right, midY);
// 3. 하단 텍스트 (전체 / 정가수의)
Rectangle subRect = new Rectangle(e.CellBounds.Left, midY, e.CellBounds.Width, e.CellBounds.Height / 2);
string subText = grdDataList.Columns[e.ColumnIndex].HeaderText;
TextRenderer.DrawText(e.Graphics, subText, boldFont, subRect, HEADER_TEXT_COLOR,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
else
{
// 일반 컬럼 (경매일자 등) - 세로 중앙 정렬을 위해 VerticalCenter 강조
TextRenderer.DrawText(e.Graphics, grdDataList.Columns[e.ColumnIndex].HeaderText, boldFont, e.CellBounds, HEADER_TEXT_COLOR,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
e.Graphics.DrawRectangle(whitePen, e.CellBounds);
e.Handled = true;
}
}
else if (e.RowIndex >= 0)
{
// 데이터 행 그리기 로직 (기존 유지)
Color rowBgColor = (e.RowIndex % 2 == 0) ? ROW_ODD_COLOR : ROW_EVEN_COLOR;
if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
rowBgColor = Color.FromArgb(215, 230, 255);
using (Brush bgBrush = new SolidBrush(rowBgColor))
using (Pen bottomLinePen = new Pen(Color.FromArgb(235, 238, 245)))
{
e.Graphics.FillRectangle(bgBrush, e.CellBounds);
string cellText = e.FormattedValue?.ToString() ?? "";
// 데이터 영역 세로 구분선 (헤더와 동일하게 그룹 구분)
if (e.ColumnIndex == 3 || e.ColumnIndex == 5)
e.Graphics.DrawLine(new Pen(Color.FromArgb(235, 238, 245), 2), e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);
TextRenderer.DrawText(e.Graphics, cellText, new Font(this.Font.FontFamily, _dynamicFontSize), e.CellBounds, Color.Black, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
e.Graphics.DrawLine(bottomLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom - 1);
e.Handled = true;
}
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Color borderColor = Color.FromArgb(36, 85, 178);
int borderRadius = 15;
int borderWidth = 2;
// System.Drawing.Drawing2D 로 올바르게 수정되었습니다.
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
using (Pen pen = new Pen(borderColor, borderWidth))
{
path.AddArc(0, 0, borderRadius, borderRadius, 180, 90);
path.AddArc(panel1.Width - borderRadius - 1, 0, borderRadius, borderRadius, 270, 90);
path.AddArc(panel1.Width - borderRadius - 1, panel1.Height - borderRadius - 1, borderRadius, borderRadius, 0, 90);
path.AddArc(0, panel1.Height - borderRadius - 1, borderRadius, borderRadius, 90, 90);
path.CloseAllFigures();
panel1.Region = new Region(path);
e.Graphics.DrawPath(pen, path);
}
}
// 타이틀 패널 내부 컨트롤들의 정확한 위치 및 잘림 방지
private void panel1_SizeChanged(object sender, EventArgs e)
{
if (panel1 == null) return;
int sideOffset = 25; // 우측/좌측 끝단 마진
// 1. 왼쪽 로고 텍스트 잘림 방지 및 세로 중앙 정렬
if (lblLogo != null)
{
lblLogo.AutoSize = false; // 자동 크기 해제 후 직접 넉넉하게 지정
lblLogo.Width = 200; // '수협중앙회'가 절대 잘리지 않을 크기
lblLogo.Height = panel1.Height; // 패널 높이만큼 꽉 채움
lblLogo.TextAlign = ContentAlignment.MiddleLeft; // 텍스트를 왼쪽 중앙에 정렬
lblLogo.Left = 100; // 패널 왼쪽에서 25픽셀 여백
lblLogo.Top = 0; // TextAlign이 중앙을 잡아주므로 Top은 0
}
// 2. 타이틀 메인 텍스트 중앙 배치
if (lblTitle != null)
{
lblTitle.AutoSize = true;
lblTitle.Left = (panel1.Width - lblTitle.Width) / 2;
lblTitle.Top = (panel1.Height - lblTitle.Height) / 2;
}
// 3. 날짜 및 시간 영역 바짝 오른쪽 정렬 및 상하 밀착 배치
int totalClockHeight = (lblDate != null ? lblDate.Height : 0) + (lblTime != null ? lblTime.Height : 0) - 5;
int clockTopStart = (panel1.Height - totalClockHeight) / 2;
if (lblDate != null)
{
//lblDate.AutoSize = true;
lblDate.Left = panel1.Width - lblDate.Width - sideOffset;
lblDate.Top = clockTopStart;
}
if (lblTime != null)
{
//lblTime.AutoSize = true;
lblTime.Left = panel1.Width - lblTime.Width - sideOffset;
lblTime.Top = (lblDate != null) ? lblDate.Bottom - 2 : clockTopStart + 25;
}
}
private void ClockTimer_Tick(object sender, EventArgs e)
{
UpdateCurrentTime();
}
private void UpdateCurrentTime()
{
string dateText = DateTime.Now.ToString("yyyy.MM.dd (ddd)");
string timeText = DateTime.Now.ToString("HH:mm");
if (lblDate != null) lblDate.Text = dateText;
if (lblTime != null) lblTime.Text = timeText;
// 텍스트 변동에 따른 우측 정렬 유지 보장
panel1_SizeChanged(null, null);
}
private void DataUpdateTime()
{
string timeText = DateTime.Now.ToString("HH:mm:ss");
if (lblDataUpdateTime != null) lblDataUpdateTime.Text = timeText + "기준";
}
private async Task DisplayPage(int page)
{
if (_dtSourceAll == null || _dtSourceAll.Rows.Count == 0 || _dtPaged == null) return;
_dtPaged.Rows.Clear();
int startIndex = (page - 1) * PAGE_SIZE;
int endIndex = Math.Min(startIndex + PAGE_SIZE, _dtSourceAll.Rows.Count);
for (int i = startIndex; i < endIndex; i++)
{
_dtPaged.ImportRow(_dtSourceAll.Rows[i]);
}
//grdDataList.DataSource = null;
grdDataList.DataSource = _dtPaged;
// 강제 새로고침
grdDataList.Refresh();
grdDataList.Invalidate();
// 데이터가 새로 바인딩된 후 템플릿 높이를 행들에 강제 적용
foreach (DataGridViewRow row in grdDataList.Rows)
{
row.Height = grdDataList.RowTemplate.Height;
}
int totalPages = (int)Math.Ceiling((double)_dtSourceAll.Rows.Count / PAGE_SIZE);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= totalPages; i++)
{
if (i == page) sb.Append("● ");
else sb.Append("• ");
}
if (lblPageIndicator != null)
{
lblPageIndicator.Text = sb.ToString().TrimEnd();
lblPageIndicator.ForeColor = Color.FromArgb(36, 85, 178);
}
grdDataList.Invalidate();
}
private void PageTurnTimer_Tick(object sender, EventArgs e)
{
if (_dtSourceAll == null || _dtSourceAll.Rows.Count == 0) return;
int totalPages = (int)Math.Ceiling((double)_dtSourceAll.Rows.Count / PAGE_SIZE);
// 현재 마지막 페이지를 보여주고 있었다면 메시지 전송
if (_currentPage == totalPages)
{
string myMac = GetMacAddress();
string responseMessage = $"{myMac}|display_complete\n";
// 별도 스레드로 보내 UI 블로킹 방지
Task.Run(() => SendServerMessage(responseMessage));
}
_currentPage++;
if (_currentPage > totalPages)
{
_currentPage = 1;
}
DisplayPage(_currentPage);
}
private void lblTitle_Click(object sender, EventArgs e) { }
private void lblTitle_Click_1(object sender, EventArgs e) { }
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
// 종료 직전 서버에 알림
Task.Run(() => SendServerMessage(GetMacAddress() + "|data_update\n"));
_isAgentRunning = false;
} }
} }
} }

View File

@@ -117,4 +117,25 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="Col0.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

267
ControlServer/AgentMonitorForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,267 @@
namespace ControlServer
{
partial class AgentMonitorForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle2 = new DataGridViewCellStyle();
lblPCName = new Label();
lblMac = new Label();
grdDataList = new DataGridView();
Col0 = new DataGridViewTextBoxColumn();
Col1 = new DataGridViewTextBoxColumn();
Col2 = new DataGridViewTextBoxColumn();
Col3 = new DataGridViewTextBoxColumn();
Col4 = new DataGridViewTextBoxColumn();
Col5 = new DataGridViewTextBoxColumn();
Col6 = new DataGridViewTextBoxColumn();
panel1 = new Panel();
lblTime = new Label();
lblDate = new Label();
imgLogo = new PictureBox();
lblLogo = new Label();
lblTitle = new Label();
lblPageIndicator = new Label();
lblDataUpdateTime = new Label();
((System.ComponentModel.ISupportInitialize)grdDataList).BeginInit();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)imgLogo).BeginInit();
SuspendLayout();
//
// lblPCName
//
lblPCName.Location = new Point(226, 57);
lblPCName.Name = "lblPCName";
lblPCName.Size = new Size(219, 39);
lblPCName.TabIndex = 0;
//
// lblMac
//
lblMac.Location = new Point(226, 141);
lblMac.Name = "lblMac";
lblMac.Size = new Size(219, 39);
lblMac.TabIndex = 1;
//
// grdDataList
//
dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle1.BackColor = SystemColors.Control;
dataGridViewCellStyle1.Font = new Font("맑은 고딕", 12F, FontStyle.Bold, GraphicsUnit.Point, 129);
dataGridViewCellStyle1.ForeColor = SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True;
grdDataList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
grdDataList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col6 });
grdDataList.Location = new Point(0, 146);
grdDataList.Name = "grdDataList";
grdDataList.RowHeadersWidth = 51;
dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter;
grdDataList.RowsDefaultCellStyle = dataGridViewCellStyle2;
grdDataList.Size = new Size(1412, 585);
grdDataList.TabIndex = 2;
grdDataList.CellPainting += grdDataList_CellPainting;
//
// Col0
//
Col0.HeaderText = "경매일자";
Col0.MinimumWidth = 6;
Col0.Name = "Col0";
Col0.Width = 200;
//
// Col1
//
Col1.HeaderText = "품목명";
Col1.MinimumWidth = 6;
Col1.Name = "Col1";
Col1.Width = 200;
//
// Col2
//
Col2.HeaderText = "산지";
Col2.MinimumWidth = 6;
Col2.Name = "Col2";
Col2.Width = 200;
//
// Col3
//
Col3.HeaderText = "전체수량";
Col3.MinimumWidth = 6;
Col3.Name = "Col3";
Col3.Width = 200;
//
// Col4
//
Col4.HeaderText = "정가수의 수량";
Col4.MinimumWidth = 6;
Col4.Name = "Col4";
Col4.Width = 200;
//
// Col5
//
Col5.HeaderText = "전체물량";
Col5.MinimumWidth = 6;
Col5.Name = "Col5";
Col5.Width = 200;
//
// Col6
//
Col6.HeaderText = "정가수의 물량";
Col6.MinimumWidth = 6;
Col6.Name = "Col6";
Col6.Width = 200;
//
// panel1
//
panel1.BackColor = SystemColors.Highlight;
panel1.Controls.Add(lblTime);
panel1.Controls.Add(lblDate);
panel1.Controls.Add(imgLogo);
panel1.Controls.Add(lblLogo);
panel1.Controls.Add(lblTitle);
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new Size(1412, 120);
panel1.TabIndex = 4;
panel1.Paint += panel1_Paint;
//
// lblTime
//
lblTime.BackColor = SystemColors.ControlDarkDark;
lblTime.Font = new Font("맑은 고딕", 24F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTime.ForeColor = SystemColors.HighlightText;
lblTime.Location = new Point(1215, 47);
lblTime.Name = "lblTime";
lblTime.Size = new Size(169, 66);
lblTime.TabIndex = 9;
lblTime.TextAlign = ContentAlignment.MiddleCenter;
//
// lblDate
//
lblDate.BackColor = SystemColors.ControlDarkDark;
lblDate.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblDate.ForeColor = SystemColors.HighlightText;
lblDate.Location = new Point(1215, 20);
lblDate.Name = "lblDate";
lblDate.Size = new Size(169, 27);
lblDate.TabIndex = 8;
lblDate.TextAlign = ContentAlignment.MiddleCenter;
// imgLogo
//
imgLogo.Location = new Point(20, 38);
imgLogo.Name = "imgLogo";
imgLogo.Size = new Size(52, 43);
imgLogo.TabIndex = 6;
imgLogo.TabStop = false;
//
// lblLogo
//
lblLogo.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblLogo.ForeColor = SystemColors.HighlightText;
lblLogo.Location = new Point(91, 0);
lblLogo.Name = "lblLogo";
lblLogo.Size = new Size(172, 120);
lblLogo.TabIndex = 5;
lblLogo.Text = "수협중앙회";
lblLogo.TextAlign = ContentAlignment.MiddleLeft;
//
// lblTitle
//
lblTitle.Font = new Font("맑은 고딕", 25.8000011F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTitle.ForeColor = SystemColors.HighlightText;
lblTitle.Location = new Point(0, 0);
lblTitle.Name = "lblTitle";
lblTitle.Size = new Size(1412, 120);
lblTitle.TabIndex = 4;
lblTitle.Text = "정가·수의매매 출하정보";
lblTitle.TextAlign = ContentAlignment.MiddleCenter;
lblTitle.Click += lblTitle_Click_1;
//
// lblPageIndicator
//
lblPageIndicator.Dock = DockStyle.Bottom;
lblPageIndicator.Font = new Font("맑은 고딕", 7.8F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblPageIndicator.ForeColor = SystemColors.HotTrack;
lblPageIndicator.Location = new Point(0, 734);
lblPageIndicator.Name = "lblPageIndicator";
lblPageIndicator.Size = new Size(1412, 19);
lblPageIndicator.TabIndex = 5;
lblPageIndicator.TextAlign = ContentAlignment.MiddleCenter;
//
// lblDataUpdateTime
//
lblDataUpdateTime.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblDataUpdateTime.Location = new Point(5, 124);
lblDataUpdateTime.Name = "lblDataUpdateTime";
lblDataUpdateTime.Size = new Size(306, 19);
lblDataUpdateTime.TabIndex = 6;
lblDataUpdateTime.Text = " ";
lblDataUpdateTime.TextAlign = ContentAlignment.MiddleLeft;
//
// Form1
//
AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1412, 753);
Controls.Add(lblDataUpdateTime);
Controls.Add(lblPageIndicator);
Controls.Add(panel1);
Controls.Add(grdDataList);
Controls.Add(lblMac);
Controls.Add(lblPCName);
Name = "Form1";
Text = "Form1";
((System.ComponentModel.ISupportInitialize)grdDataList).EndInit();
panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)imgLogo).EndInit();
ResumeLayout(false);
}
#endregion
private Label lblPCName;
private Label lblMac;
private DataGridView grdDataList;
private DataGridViewTextBoxColumn Col0;
private DataGridViewTextBoxColumn Col1;
private DataGridViewTextBoxColumn Col2;
private DataGridViewTextBoxColumn Col3;
private DataGridViewTextBoxColumn Col4;
private DataGridViewTextBoxColumn Col5;
private DataGridViewTextBoxColumn Col6;
private Panel panel1;
private Label lblTitle;
private Label lblLogo;
private PictureBox imgLogo;
private Label lblDate;
private Label lblTime;
private Label lblPageIndicator;
private Label lblDataUpdateTime;
}
}

View File

@@ -0,0 +1,704 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Windows.Forms.LinkLabel;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
namespace ControlServer
{
public partial class AgentMonitorForm : Form
{
// 색상 정의 (Hex 코드 대신 RGB 사용)
private readonly Color HEADER_BG_COLOR = Color.FromArgb(36, 85, 178);
private readonly Color HEADER_TEXT_COLOR = Color.White;
private readonly Color ROW_EVEN_COLOR = Color.FromArgb(245, 248, 255); // 짝수 행 (연한 파란색 계열)
private readonly Color ROW_ODD_COLOR = Color.White; // 홀수 행 (흰색)
private readonly Color TEXT_BLUE_COLOR = Color.FromArgb(24, 60, 150); // 파란색 텍스트
private DataTable _dtSourceAll; // 전체 데이터를 담을 DataTable
private DataTable _dtPaged; // 현재 페이지에 해당하는 데이터만 담을 DataTable
private int _currentPage = 1;
private const int PAGE_SIZE = 5; // 한 페이지당 5행씩
private int _dynamicFontSize = 12; // 동적으로 바뀔 폰트 크기 (기본값)
private System.Windows.Forms.Timer _pageTurnTimer;
private System.Windows.Forms.Timer _clockTimer;
private bool _isAgentRunning = true; // 에이전트 루프 제어 플래그
private NetworkStream _currentStream = null;
private readonly object _streamLock = new object();
private Button _btnMinimize;
private Button _btnClose;
public AgentMonitorForm()
{
InitializeComponent();
// 1. 폼 최대화 및 테두리 제거 (현황판/키오스크 스타일)
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
// 고정 도킹 해제하여 동적 배치 적용
if (panel1 != null)
{
panel1.Dock = DockStyle.None;
panel1.Height = 140; // 전체 화면 비율에 맞춰 타이틀 패널 높이 조절
}
// 라벨들의 개별 Dock 설정을 해제하여 디자이너에서 배치한 원래 위치(좌측/우측)를 유지하도록 합니다.
if (lblTime != null) lblTime.Dock = DockStyle.None;
if (lblDate != null) lblDate.Dock = DockStyle.None;
if (lblTitle != null) lblTitle.Dock = DockStyle.None;
if (lblDataUpdateTime != null)
{
lblDataUpdateTime.Dock = DockStyle.None;
lblDataUpdateTime.AutoSize = true;
}
// 3.그리드가 기준시간 밑으로 오도록 도킹 해제 및 여백 초기화
grdDataList.Dock = DockStyle.None;
grdDataList.Padding = new Padding(0); // 기존 오작동하던 패딩 제거
// 4. 화면 해상도가 바뀌거나 최대화될 때 컨트롤 위치를 전체적으로 재계산
this.SizeChanged += (s, e) =>
{
int sideMargin = 25; // 좌우 고정 여백
int topMargin = 20; // 타이틀 패널 위쪽 살짝 여백 추가
int areaWidth = this.ClientSize.Width - (sideMargin * 2);
// A. 타이틀 패널 위치 및 크기 조절 (그리드와 넓이 동기화 및 상단 여백)
if (panel1 != null)
{
panel1.SetBounds(sideMargin, topMargin, areaWidth, panel1.Height);
// 타이틀 내부 컨트롤 정렬 강제 호출
panel1_SizeChanged(null, null);
}
// B. 기준 시간 라벨 배치 (타이틀 패널 아래로 15픽셀 여백)
if (lblDataUpdateTime != null && panel1 != null)
{
lblDataUpdateTime.Location = new Point(sideMargin, panel1.Bottom + 15);
lblDataUpdateTime.BringToFront();
}
// C. 그리드 배치 (기준시간 라벨 아랫변 + 15픽셀 여백)
if (lblDataUpdateTime != null)
{
int gridTop = lblDataUpdateTime.Bottom + 15;
int gridHeight = this.ClientSize.Height - gridTop - 60;
if (areaWidth > 0 && gridHeight > 0)
{
grdDataList.SetBounds(sideMargin, gridTop, areaWidth, gridHeight);
// 가용 높이에 맞게 행 높이 동적 계산 (한 번에 5개 고정)
int headerHeight = grdDataList.ColumnHeadersHeight;
int availableHeight = gridHeight - headerHeight;
if (availableHeight > 0)
{
// 정밀도를 위해 가용한 높이를 PAGE_SIZE(5)로 나눈 몫을 계산
int dynamicRowHeight = availableHeight / PAGE_SIZE;
// 앞으로 추가될 행의 기본 높이 설정
grdDataList.RowTemplate.Height = dynamicRowHeight;
// 현재 이미 그리드에 바인딩되어 있는 행들의 높이도 일괄 변경
// 폰트 크기가 최소 12pt ~ 최대 24pt 사이에 머물도록 제한
_dynamicFontSize = Math.Clamp((int)(dynamicRowHeight * 0.16), 12, 24);
foreach (DataGridViewRow row in grdDataList.Rows)
{
row.Height = dynamicRowHeight;
}
}
//그리드 모서리 둥글게 깎기
UpdateGridRegion();
}
}
// 하단 페이지 점(● • •) 위치 정중앙 하단으로 재배치
if (lblPageIndicator != null)
{
lblPageIndicator.Dock = DockStyle.None;
lblPageIndicator.AutoSize = true;
lblPageIndicator.Location = new Point(
(this.ClientSize.Width - lblPageIndicator.Width) / 2,
this.ClientSize.Height - 40
);
lblPageIndicator.BringToFront();
}
};
// DataGridView 내부 컬럼들도 우측 빈 공간(회색 여백) 없이 꽉 차게 채움
grdDataList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grdDataList.ColumnHeadersVisible = true;
// DataGridView의 기본 스타일 및 그리드선 숨기기 설정
grdDataList.CellPainting -= grdDataList_CellPainting;
grdDataList.CellPainting += grdDataList_CellPainting;
grdDataList.AutoGenerateColumns = false; // 자동 컬럼 생성 방지
grdDataList.RowHeadersVisible = false; // 행 헤더 숨기기
grdDataList.AllowUserToAddRows = false; // 빈 행 추가 방지
grdDataList.AllowUserToResizeColumns = false; // 컬럼 너비 조정 불가
grdDataList.AllowUserToResizeRows = false; // 행 높이 조정 불가
grdDataList.ReadOnly = true; // 읽기 전용
grdDataList.AllowUserToDeleteRows = false; // 행 삭제 방지
grdDataList.ColumnHeadersHeight = 81; // 헤더 높이를 81로 설정 (2줄 헤더 공간 확보)
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
grdDataList.EnableHeadersVisualStyles = false; // 커스텀 헤더 스타일 적용을 위해 필수
grdDataList.CellBorderStyle = DataGridViewCellBorderStyle.None; // 셀 테두리(그리드선) 제거
grdDataList.RowTemplate.Height = 100; // 데이터 행 높이를 100으로 설정
grdDataList.BorderStyle = BorderStyle.None; // 컨트롤 외곽선 제거
// 사용자가 컬럼을 클릭해도 정렬되지 않도록 설정 (안정적인 화면 유지)
grdDataList.ColumnAdded += (s, e) =>
{
e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
};
// 시계 타이머 설정 (1초마다 업데이트)
_clockTimer = new System.Windows.Forms.Timer();
_clockTimer.Interval = 1000;
_clockTimer.Tick += ClockTimer_Tick;
// 페이지 전환 타이머 설정 (5초마다 업데이트)
_pageTurnTimer = new System.Windows.Forms.Timer();
_pageTurnTimer.Interval = 5000;
_pageTurnTimer.Tick += PageTurnTimer_Tick;
this.Load += Form1_Load;
}
// 데이터그리드뷰 영역을 둥글게 깎아주는 헬퍼 메서드
private void UpdateGridRegion()
{
if (grdDataList.Width <= 0 || grdDataList.Height <= 0) return;
int radius = 15;
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(0, 0, radius, radius, 180, 90);
path.AddArc(grdDataList.Width - radius, 0, radius, radius, 270, 90);
path.AddArc(grdDataList.Width - radius, grdDataList.Height - radius, radius, radius, 0, 90);
path.AddArc(0, grdDataList.Height - radius, radius, radius, 90, 90);
path.CloseAllFigures();
grdDataList.Region = new Region(path);
}
}
private void Form1_Load(object sender, EventArgs e)
{
// 컬럼 프로퍼티 매핑 초기화 선행
InitGridColumnProperties();
// 한 번 더 명시적으로 정렬 비활성화
foreach (DataGridViewColumn col in grdDataList.Columns)
{
col.SortMode = DataGridViewColumnSortMode.NotSortable;
}
// 시계 시작
_clockTimer.Start();
UpdateCurrentTime();
// [수정] XML 테스트 파일 생성 및 직접 바인딩 로직을 제거했습니다.
// 연결 전까지는 그리드가 빈 상태(리스트 없음)로 대기합니다.
grdDataList.DataSource = null;
// 페이지 타이머 시작
_pageTurnTimer.Start();
// 백그라운드 소켓 통신 시작 (비동기 Task 활용으로 UI 블로킹 방지)
Task.Run(() => StartAgentTask());
}
// 그리드 내부 컬럼에 프로퍼티 명을 미리 지정해 주는 헬퍼 메서드
private void InitGridColumnProperties()
{
foreach (DataGridViewColumn col in grdDataList.Columns)
{
if (col.HeaderText.Contains("경매일자")) col.DataPropertyName = "aucDate";
else if (col.HeaderText.Contains("품목명")) col.DataPropertyName = "itemName";
else if (col.HeaderText.Contains("산지")) col.DataPropertyName = "origin";
else if (col.HeaderText.Contains("전체수량") || (col.HeaderText.Contains("전체") && col.Index == 3)) col.DataPropertyName = "totalQty";
else if (col.HeaderText.Contains("정가수의수량") || col.HeaderText.Contains("정가수의 수량") || col.Index == 4) col.DataPropertyName = "fixPriceQty";
else if (col.HeaderText.Contains("전체물량") || (col.HeaderText.Contains("전체") && col.Index == 5)) col.DataPropertyName = "totalAmt";
else if (col.HeaderText.Contains("정가수의물량") || col.HeaderText.Contains("정가수의 물량") || col.Index == 6) col.DataPropertyName = "fixPriceAmt";
if (col.Index >= 3 && col.Index <= 6)
{
col.ValueType = typeof(int);
col.DefaultCellStyle.Format = "N0";
}
}
}
// 서버와의 소켓 통신을 관리하는 백그라운드 메서드
private void StartAgentTask()
{
if (DisableSocketCommunication) return; // 외부 모드면 통신 루프 진입 차단
while (_isAgentRunning)
{
try
{
using (TcpClient client = new TcpClient("192.168.219.48", 9999))
using (NetworkStream stream = client.GetStream())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8))
{
// [인증] 서버에 MAC 전송
byte[] macBytes = Encoding.UTF8.GetBytes(GetMacAddress() + "\n");
stream.Write(macBytes, 0, macBytes.Length);
string buffer = ""; // 데이터를 쌓아둘 버퍼
_currentStream = stream; // 전송용 스트림 할당
while (client.Connected && _isAgentRunning)
{
string line = reader.ReadLine();
if (string.IsNullOrEmpty(line))
{
break;
}
if (line.StartsWith("SET_TIME|"))
{
string[] parts = line.Split('|');
if (parts.Length > 1 && int.TryParse(parts[1], out int newInterval))
{
this.BeginInvoke(new Action(() => {
_pageTurnTimer.Interval = newInterval * 1000; // 초 단위를 밀리초로 변환
}));
}
}
buffer += line; // 들어오는 내용을 버퍼에 누적
// 전체 데이터가 들어왔는지 확인 (서버가 마지막에 </AuctionRows>를 보낸다고 가정)
if (buffer.Contains("<AuctionRows>") && buffer.Contains("</AuctionRows>"))
{
ParseAndBindServerData(buffer);
buffer = ""; // 파싱 후 버퍼 비우기
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("통신 끊김, 5초 후 재시도: " + ex.Message);
Thread.Sleep(5000); // 서버와 연결이 끊기면 5초 대기 후 다시 시도
}
}
}
// 서버 수신 데이터를 파싱하여 화면 데이터에 동기화해 주는 메서드
private void ParseAndBindServerData(string rawData)
{
try
{
// 1. XML 문자열 파싱
XDocument doc = XDocument.Parse(rawData);
DataTable dt = new DataTable();
dt.Columns.Add("aucDate", typeof(string));
dt.Columns.Add("itemName", typeof(string));
dt.Columns.Add("origin", typeof(string));
dt.Columns.Add("totalQty", typeof(int));
dt.Columns.Add("fixPriceQty", typeof(int));
dt.Columns.Add("totalAmt", typeof(int));
dt.Columns.Add("fixPriceAmt", typeof(int));
// 2. <AuctionTable> 태그를 찾아서 행 추가
foreach (var row in doc.Descendants("AuctionTable"))
{
dt.Rows.Add(
row.Element("aucDate")?.Value,
row.Element("itemName")?.Value,
row.Element("origin")?.Value,
int.TryParse(row.Element("totalQty")?.Value.Replace(",", ""), out int tq) ? tq : 0,
int.TryParse(row.Element("fixPriceQty")?.Value.Replace(",", ""), out int fq) ? fq : 0,
int.TryParse(row.Element("totalAmt")?.Value.Replace(",", ""), out int ta) ? ta : 0,
int.TryParse(row.Element("fixPriceAmt")?.Value.Replace(",", ""), out int fa) ? fa : 0
);
}
// 3. UI 바인딩
this.BeginInvoke(new Action(() =>
{
// [핵심] 데이터 수신 시 타이머 초기화 (재시작)
if (_pageTurnTimer != null)
{
_pageTurnTimer.Stop(); // 현재 카운트 중지
}
_dtSourceAll = dt;
_dtPaged = _dtSourceAll.Clone();
_currentPage = 1;
if (_dtSourceAll.Rows.Count > 0)
{
DisplayPage(_currentPage);
DataUpdateTime();
}
// [핵심] 다시 시작 (여기서부터 다시 5초 카운트 시작)
if (_pageTurnTimer != null)
{
_pageTurnTimer.Start();
}
}));
}
catch (Exception ex)
{
// 파싱 에러 상세 확인을 위해 에러 메시지 출력
Console.WriteLine("XML 파싱 에러: " + ex.Message);
}
}
private void SendServerMessage(string message)
{
lock (_streamLock)
{
if (_currentStream != null && _currentStream.CanWrite)
{
try
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
_currentStream.Write(buffer, 0, buffer.Length);
_currentStream.Flush();
Console.WriteLine("서버로 상태 전송 완료: " + message.Trim());
}
catch (Exception ex)
{
Console.WriteLine("서버 상태 전송 오류: " + ex.Message);
}
}
}
}
public string GetMacAddress()
{
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel &&
ni.OperationalStatus == OperationalStatus.Up)
{
string mac = ni.GetPhysicalAddress().ToString();
if (!string.IsNullOrEmpty(mac)) return mac;
}
}
return "MAC Not Found";
}
private void grdDataList_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0) return;
// 현재 열이 수량/물량 그룹인지 확인
bool isDataGroup = (e.ColumnIndex >= 3 && e.ColumnIndex <= 6);
if (e.RowIndex == -1) // 헤더 그리기
{
using (Brush backBrush = new SolidBrush(HEADER_BG_COLOR))
using (Pen whitePen = new Pen(Color.White, 1))
using (Pen groupLinePen = new Pen(Color.White, 2))
using (Font boldFont = new Font(this.Font.FontFamily, 14, FontStyle.Bold)) // 폰트 크기 조정
{
e.Graphics.FillRectangle(backBrush, e.CellBounds);
if (isDataGroup)
{
// 1. 수탁수량/수탁물량 (상단)
Rectangle topRect = new Rectangle(e.CellBounds.Left, e.CellBounds.Top, e.CellBounds.Width, e.CellBounds.Height / 2);
if (e.ColumnIndex == 3) TextRenderer.DrawText(e.Graphics, "수 탁", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 4) TextRenderer.DrawText(e.Graphics, "수 량", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 5) TextRenderer.DrawText(e.Graphics, "수 탁", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
else if (e.ColumnIndex == 6) TextRenderer.DrawText(e.Graphics, "물 량", boldFont, topRect, HEADER_TEXT_COLOR, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak);
//TextFormatFlags topAlign = (e.ColumnIndex == 3 || e.ColumnIndex == 5) ? TextFormatFlags.Right : TextFormatFlags.Left; // 수탁은 오른쪽, 수량/물량은 왼쪽 정렬
// 2. 중간 구분선
int midY = e.CellBounds.Top + (e.CellBounds.Height / 2);
e.Graphics.DrawLine(whitePen, e.CellBounds.Left, midY, e.CellBounds.Right, midY);
// 3. 하단 텍스트 (전체 / 정가수의)
Rectangle subRect = new Rectangle(e.CellBounds.Left, midY, e.CellBounds.Width, e.CellBounds.Height / 2);
string subText = grdDataList.Columns[e.ColumnIndex].HeaderText;
TextRenderer.DrawText(e.Graphics, subText, boldFont, subRect, HEADER_TEXT_COLOR,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
else
{
// 일반 컬럼 (경매일자 등) - 세로 중앙 정렬을 위해 VerticalCenter 강조
TextRenderer.DrawText(e.Graphics, grdDataList.Columns[e.ColumnIndex].HeaderText, boldFont, e.CellBounds, HEADER_TEXT_COLOR,
TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
e.Graphics.DrawRectangle(whitePen, e.CellBounds);
e.Handled = true;
}
}
else if (e.RowIndex >= 0)
{
// 데이터 행 그리기 로직 (기존 유지)
Color rowBgColor = (e.RowIndex % 2 == 0) ? ROW_ODD_COLOR : ROW_EVEN_COLOR;
if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
rowBgColor = Color.FromArgb(215, 230, 255);
using (Brush bgBrush = new SolidBrush(rowBgColor))
using (Pen bottomLinePen = new Pen(Color.FromArgb(235, 238, 245)))
{
e.Graphics.FillRectangle(bgBrush, e.CellBounds);
string cellText = e.FormattedValue?.ToString() ?? "";
// 데이터 영역 세로 구분선 (헤더와 동일하게 그룹 구분)
if (e.ColumnIndex == 3 || e.ColumnIndex == 5)
e.Graphics.DrawLine(new Pen(Color.FromArgb(235, 238, 245), 2), e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);
TextRenderer.DrawText(e.Graphics, cellText, new Font(this.Font.FontFamily, _dynamicFontSize), e.CellBounds, Color.Black, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
e.Graphics.DrawLine(bottomLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom - 1);
e.Handled = true;
}
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Color borderColor = Color.FromArgb(36, 85, 178);
int borderRadius = 15;
int borderWidth = 2;
// System.Drawing.Drawing2D 로 올바르게 수정되었습니다.
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
using (System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath())
using (Pen pen = new Pen(borderColor, borderWidth))
{
path.AddArc(0, 0, borderRadius, borderRadius, 180, 90);
path.AddArc(panel1.Width - borderRadius - 1, 0, borderRadius, borderRadius, 270, 90);
path.AddArc(panel1.Width - borderRadius - 1, panel1.Height - borderRadius - 1, borderRadius, borderRadius, 0, 90);
path.AddArc(0, panel1.Height - borderRadius - 1, borderRadius, borderRadius, 90, 90);
path.CloseAllFigures();
panel1.Region = new Region(path);
e.Graphics.DrawPath(pen, path);
}
}
// 타이틀 패널 내부 컨트롤들의 정확한 위치 및 잘림 방지
private void panel1_SizeChanged(object sender, EventArgs e)
{
if (panel1 == null) return;
int sideOffset = 25; // 우측/좌측 끝단 마진
// 1. 왼쪽 로고 텍스트 잘림 방지 및 세로 중앙 정렬
if (lblLogo != null)
{
lblLogo.AutoSize = false; // 자동 크기 해제 후 직접 넉넉하게 지정
lblLogo.Width = 200; // '수협중앙회'가 절대 잘리지 않을 크기
lblLogo.Height = panel1.Height; // 패널 높이만큼 꽉 채움
lblLogo.TextAlign = ContentAlignment.MiddleLeft; // 텍스트를 왼쪽 중앙에 정렬
lblLogo.Left = 100; // 패널 왼쪽에서 25픽셀 여백
lblLogo.Top = 0; // TextAlign이 중앙을 잡아주므로 Top은 0
}
// 2. 타이틀 메인 텍스트 중앙 배치
if (lblTitle != null)
{
lblTitle.AutoSize = true;
lblTitle.Left = (panel1.Width - lblTitle.Width) / 2;
lblTitle.Top = (panel1.Height - lblTitle.Height) / 2;
}
// 3. 날짜 및 시간 영역 바짝 오른쪽 정렬 및 상하 밀착 배치
int totalClockHeight = (lblDate != null ? lblDate.Height : 0) + (lblTime != null ? lblTime.Height : 0) - 5;
int clockTopStart = (panel1.Height - totalClockHeight) / 2;
if (lblDate != null)
{
//lblDate.AutoSize = true;
lblDate.Left = panel1.Width - lblDate.Width - sideOffset;
lblDate.Top = clockTopStart;
}
if (lblTime != null)
{
//lblTime.AutoSize = true;
lblTime.Left = panel1.Width - lblTime.Width - sideOffset;
lblTime.Top = (lblDate != null) ? lblDate.Bottom - 2 : clockTopStart + 25;
}
}
private void ClockTimer_Tick(object sender, EventArgs e)
{
UpdateCurrentTime();
}
private void UpdateCurrentTime()
{
string dateText = DateTime.Now.ToString("yyyy.MM.dd (ddd)");
string timeText = DateTime.Now.ToString("HH:mm");
if (lblDate != null) lblDate.Text = dateText;
if (lblTime != null) lblTime.Text = timeText;
// 텍스트 변동에 따른 우측 정렬 유지 보장
panel1_SizeChanged(null, null);
}
private void DataUpdateTime()
{
string timeText = DateTime.Now.ToString("HH:mm:ss");
if (lblDataUpdateTime != null) lblDataUpdateTime.Text = timeText + "기준";
}
private async Task DisplayPage(int page)
{
if (_dtSourceAll == null || _dtSourceAll.Rows.Count == 0 || _dtPaged == null) return;
_dtPaged.Rows.Clear();
int startIndex = (page - 1) * PAGE_SIZE;
int endIndex = Math.Min(startIndex + PAGE_SIZE, _dtSourceAll.Rows.Count);
for (int i = startIndex; i < endIndex; i++)
{
_dtPaged.ImportRow(_dtSourceAll.Rows[i]);
}
//grdDataList.DataSource = null;
grdDataList.DataSource = _dtPaged;
// 강제 새로고침
grdDataList.Refresh();
grdDataList.Invalidate();
// 데이터가 새로 바인딩된 후 템플릿 높이를 행들에 강제 적용
foreach (DataGridViewRow row in grdDataList.Rows)
{
row.Height = grdDataList.RowTemplate.Height;
}
int totalPages = (int)Math.Ceiling((double)_dtSourceAll.Rows.Count / PAGE_SIZE);
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= totalPages; i++)
{
if (i == page) sb.Append("● ");
else sb.Append("• ");
}
if (lblPageIndicator != null)
{
lblPageIndicator.Text = sb.ToString().TrimEnd();
lblPageIndicator.ForeColor = Color.FromArgb(36, 85, 178);
}
grdDataList.Invalidate();
//if (page == totalPages)
//{
// string myMac = GetMacAddress();
// string responseMessage = $"{myMac}|display_complete\n";
// SendServerMessage(responseMessage);
//}
}
private void PageTurnTimer_Tick(object sender, EventArgs e)
{
if (_dtSourceAll == null || _dtSourceAll.Rows.Count == 0) return;
int totalPages = (int)Math.Ceiling((double)_dtSourceAll.Rows.Count / PAGE_SIZE);
// 현재 마지막 페이지를 보여주고 있었다면 메시지 전송
if (_currentPage == totalPages)
{
string myMac = GetMacAddress();
string responseMessage = $"{myMac}|display_complete\n";
// 별도 스레드로 보내 UI 블로킹 방지
Task.Run(() => SendServerMessage(responseMessage));
}
_currentPage++;
if (_currentPage > totalPages)
{
_currentPage = 1;
}
DisplayPage(_currentPage);
}
private void lblTitle_Click(object sender, EventArgs e) { }
private void lblTitle_Click_1(object sender, EventArgs e) { }
public void UpdateMonitorData(string xmlData)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => UpdateMonitorData(xmlData)));
return;
}
// 외부 주입 모드일 때는 기존 소켓 통신 로직을 정지시키거나 데이터만 바로 파싱하여 표시
_isAgentRunning = false; // 소켓 루프 정지 (이미 열려있는 폼이라면)
// ParseAndBindServerData는 이미 구현되어 있으므로 그대로 재사용 가능
ParseAndBindServerData(xmlData);
System.Diagnostics.Debug.WriteLine($"[모니터링 갱신] 외부 데이터 바인딩 완료: {xmlData.Length} bytes");
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool DisableSocketCommunication { get; set; } = false;
private void InitializeCustomButtons()
{
// 최소화 버튼 설정
_btnMinimize = new Button { Text = "—", Size = new Size(40, 40), FlatStyle = FlatStyle.Flat };
_btnMinimize.FlatAppearance.BorderSize = 0;
_btnMinimize.Click += (s, e) => { this.WindowState = FormWindowState.Minimized; };
// 닫기 버튼 설정
_btnClose = new Button { Text = "✕", Size = new Size(40, 40), FlatStyle = FlatStyle.Flat };
_btnClose.FlatAppearance.BorderSize = 0;
_btnClose.Click += (s, e) => { this.Close(); };
// 타이틀 패널(panel1)에 추가
panel1.Controls.Add(_btnMinimize);
panel1.Controls.Add(_btnClose);
// 위치 조정 (우측 상단 배치)
_btnClose.Location = new Point(panel1.Width - 50, 5);
_btnMinimize.Location = new Point(panel1.Width - 95, 5);
_btnClose.BringToFront();
_btnMinimize.BringToFront();
}
}
}

View File

@@ -117,10 +117,13 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="Col5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col0.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Col0.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Col3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
@@ -129,10 +132,10 @@
<metadata name="Col4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Col5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Col7.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

Binary file not shown.

View File

@@ -11,9 +11,13 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="RestSharp" Version="114.0.0" /> <PackageReference Include="RestSharp" Version="114.0.0" />
<PackageReference Include="System.Data.OleDb" Version="10.0.9" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="AgentMonitorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Properties\Resources.Designer.cs"> <Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -0,0 +1,215 @@
using System;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Text;
namespace ControlServer
{
public class DbFileManager
{
// ⚠️ 실제 개발 환경에 맞게 데이터 소스, 아이디, 비밀번호를 변경해 주세요.
private readonly string _connectionString = "Provider=Tibero.OLEDB;Data Source=YourDB;User Id=YourID;Password=YourPassword;";
private readonly string _fileDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SendData");
public DbFileManager()
{
if (!Directory.Exists(_fileDirPath))
{
Directory.CreateDirectory(_fileDirPath);
}
}
/// <summary>
/// [Form1 연동 규격] DB에서 에이전트 IP 혹은 단말기명에 맞는 데이터를 가져와
/// XML 파일로 저장하고, 가상 모니터 폼 갱신을 위해 DataTable을 반환
/// </summary>
/// <param name="terminalName">단말기 식별자 (IP 주소 또는 단말기명)</param>
/// <returns>가상 모니터링 그리드에 바인딩할 DataTable</returns>
public DataTable GetTerminalData(string terminalName)
{
// 1. 에이전트 화면 규격(AuctionTable)과 컬럼 구조 정의
DataTable dt = new DataTable("AuctionTable");
dt.Columns.Add("aucDate", typeof(string));
dt.Columns.Add("itemName", typeof(string));
dt.Columns.Add("origin", typeof(string));
dt.Columns.Add("totalQty", typeof(int));
dt.Columns.Add("fixPriceQty", typeof(int));
dt.Columns.Add("totalAmt", typeof(int));
dt.Columns.Add("fixPriceAmt", typeof(int));
// 2. Tibero DB 조회 쿼리
string query = @"SELECT AUC_DATE, ITEM_NAME, ORIGIN, TOTAL_QTY, FIX_QTY, TOTAL_AMT, FIX_AMT
FROM FIXED_PRICE_TRADE
WHERE TERMINAL_NAME = ?";
using (OleDbConnection conn = new OleDbConnection(_connectionString))
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("@TerminalName", terminalName);
try
{
conn.Open();
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
dt.Rows.Add(
reader["AUC_DATE"]?.ToString() ?? "",
reader["ITEM_NAME"]?.ToString() ?? "",
reader["ORIGIN"]?.ToString() ?? "",
reader["TOTAL_QTY"] != DBNull.Value ? Convert.ToInt32(reader["TOTAL_QTY"]) : 0,
reader["FIX_QTY"] != DBNull.Value ? Convert.ToInt32(reader["FIX_QTY"]) : 0,
reader["TOTAL_AMT"] != DBNull.Value ? Convert.ToInt32(reader["TOTAL_AMT"]) : 0,
reader["FIX_AMT"] != DBNull.Value ? Convert.ToInt32(reader["FIX_AMT"]) : 0
);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"[{terminalName}] DB 연동 실패: " + ex.Message);
// 에러 발생 시 프로그램이 뻗지 않도록 null 반환 처리
return null;
}
}
}
// 3. 조회 데이터가 전혀 없을 경우 가상 모니터 가독성을 위한 기본 행 처리
if (dt.Rows.Count == 0)
{
string today = DateTime.Now.ToString("MM.dd");
dt.Rows.Add(today, "조회데이터 없음", "-", 0, 0, 0, 0);
}
// 4. 에이전트 전송 호환용 내부 로컬 XML 파일 백업 저장 (.xml)
string fileName = $"{terminalName}.xml";
string fullPath = Path.Combine(_fileDirPath, fileName);
try
{
dt.WriteXml(fullPath, XmlWriteMode.WriteSchema);
Console.WriteLine($"[XML 로컬 백업 완료] {fullPath}");
}
catch (Exception ex)
{
Console.WriteLine($"[{terminalName}] XML 파일 저장 실패: " + ex.Message);
}
// Form1의 agentCurrentData 변수로 데이터 테이블을 그대로 토스
return dt;
}
/// <summary>
/// 기존 소켓 전송 규격 유지용 메서드 (필요시 사용)
/// </summary>
public string CreateAndSaveTerminalFile(string terminalName)
{
//DataTable dt = GetTerminalData(terminalName);
//if (dt == null) return "DB_ERROR|조회 실패";
//using (StringWriter sw = new StringWriter())
//{
// dt.WriteXml(sw, XmlWriteMode.WriteSchema);
// return sw.ToString();
//}
// 파일 경로 설정
string filePath = GetTerminalFilePath(terminalName);
// -----------------------------------------------------------------
// [임시 테스트용 데이터 하드코딩] DB 연동 전까지 사용할 더미 데이터
// -----------------------------------------------------------------
string xmlData =
"<AuctionRows>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목1</itemName>\n" +
" <origin>테스트산지1</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목2</itemName>\n" +
" <origin>테스트산지2</origin>\n" +
" <totalQty>1030</totalQty>\n" +
" <fixPriceQty>500</fixPriceQty>\n" +
" <totalAmt>4400</totalAmt>\n" +
" <fixPriceAmt>2000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목3</itemName>\n" +
" <origin>테스트산지3</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목4</itemName>\n" +
" <origin>테스트산지4</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목5</itemName>\n" +
" <origin>테스트산지5</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목6</itemName>\n" +
" <origin>테스트산지6</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목7</itemName>\n" +
" <origin>테스트산지7</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
" <AuctionTable>\n" +
$" <aucDate>{DateTime.Now:MM.dd}</aucDate>\n" +
" <itemName>테스트품목8</itemName>\n" +
" <origin>테스트산지8</origin>\n" +
" <totalQty>1000</totalQty>\n" +
" <fixPriceQty>800</fixPriceQty>\n" +
" <totalAmt>5000</totalAmt>\n" +
" <fixPriceAmt>4000</fixPriceAmt>\n" +
" </AuctionTable>\n" +
"</AuctionRows>";
// 2. 파일 저장
File.WriteAllText(filePath, xmlData);
Console.WriteLine($"[DB Manager] XML 파일 생성 완료: {filePath}");
return xmlData; // 데이터 반환
}
public string GetTerminalFilePath(string terminalName)
{
// 확장자를 .xml로 통일
return Path.Combine(_fileDirPath, $"{terminalName}.xml");
}
}
}

View File

@@ -36,18 +36,17 @@
DataGridViewCellStyle dataGridViewCellStyle5 = new DataGridViewCellStyle(); DataGridViewCellStyle dataGridViewCellStyle5 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle6 = new DataGridViewCellStyle(); DataGridViewCellStyle dataGridViewCellStyle6 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle7 = new DataGridViewCellStyle(); DataGridViewCellStyle dataGridViewCellStyle7 = new DataGridViewCellStyle();
pannGray = new Panel(); pannGray = new RoundedPanel();
lblTotCnt = new Label(); lblTotCnt = new Label();
lblGrayTitle = new Label(); lblGrayTitle = new Label();
pannBlue = new Panel(); pannBlue = new RoundedPanel();
lblRunningCnt = new Label(); lblRunningCnt = new Label();
lblBlueTitle = new Label(); lblBlueTitle = new Label();
grdTotList = new DataGridView(); grdTotList = new DataGridView();
btnLog = new Button();
btnRegister = new Button(); btnRegister = new Button();
btnDataUpdate = new Button(); btnDataUpdate = new Button();
txtSearch = new TextBox(); txtSearch = new TextBox();
pictureBox1 = new PictureBox(); imgSearch = new PictureBox();
Col0 = new DataGridViewTextBoxColumn(); Col0 = new DataGridViewTextBoxColumn();
Col1 = new DataGridViewTextBoxColumn(); Col1 = new DataGridViewTextBoxColumn();
Col2 = new DataGridViewTextBoxColumn(); Col2 = new DataGridViewTextBoxColumn();
@@ -55,10 +54,13 @@
Col4 = new DataGridViewTextBoxColumn(); Col4 = new DataGridViewTextBoxColumn();
Col5 = new DataGridViewTextBoxColumn(); Col5 = new DataGridViewTextBoxColumn();
Col8 = new DataGridViewTextBoxColumn(); Col8 = new DataGridViewTextBoxColumn();
Col9 = new DataGridViewTextBoxColumn();
Col10 = new DataGridViewTextBoxColumn();
Col11 = new DataGridViewTextBoxColumn();
pannGray.SuspendLayout(); pannGray.SuspendLayout();
pannBlue.SuspendLayout(); pannBlue.SuspendLayout();
((System.ComponentModel.ISupportInitialize)grdTotList).BeginInit(); ((System.ComponentModel.ISupportInitialize)grdTotList).BeginInit();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); ((System.ComponentModel.ISupportInitialize)imgSearch).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// pannGray // pannGray
@@ -69,12 +71,11 @@
pannGray.Name = "pannGray"; pannGray.Name = "pannGray";
pannGray.Size = new Size(190, 120); pannGray.Size = new Size(190, 120);
pannGray.TabIndex = 0; pannGray.TabIndex = 0;
pannGray.Paint += pannGray_Paint;
// //
// lblTotCnt // lblTotCnt
// //
lblTotCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129); lblTotCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129);
lblTotCnt.ForeColor = SystemColors.HighlightText; lblTotCnt.ForeColor = SystemColors.GrayText;
lblTotCnt.Location = new Point(0, 56); lblTotCnt.Location = new Point(0, 56);
lblTotCnt.Name = "lblTotCnt"; lblTotCnt.Name = "lblTotCnt";
lblTotCnt.Size = new Size(190, 48); lblTotCnt.Size = new Size(190, 48);
@@ -84,10 +85,11 @@
// //
// lblGrayTitle // lblGrayTitle
// //
lblGrayTitle.AutoSize = true; lblGrayTitle.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblGrayTitle.Location = new Point(33, 20); lblGrayTitle.ForeColor = SystemColors.ControlDarkDark;
lblGrayTitle.Location = new Point(0, 20);
lblGrayTitle.Name = "lblGrayTitle"; lblGrayTitle.Name = "lblGrayTitle";
lblGrayTitle.Size = new Size(124, 20); lblGrayTitle.Size = new Size(190, 20);
lblGrayTitle.TabIndex = 0; lblGrayTitle.TabIndex = 0;
lblGrayTitle.Text = "현재 단말기 대수"; lblGrayTitle.Text = "현재 단말기 대수";
lblGrayTitle.TextAlign = ContentAlignment.MiddleCenter; lblGrayTitle.TextAlign = ContentAlignment.MiddleCenter;
@@ -100,12 +102,11 @@
pannBlue.Name = "pannBlue"; pannBlue.Name = "pannBlue";
pannBlue.Size = new Size(190, 120); pannBlue.Size = new Size(190, 120);
pannBlue.TabIndex = 2; pannBlue.TabIndex = 2;
pannBlue.Paint += pannBlue_Paint;
// //
// lblRunningCnt // lblRunningCnt
// //
lblRunningCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129); lblRunningCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129);
lblRunningCnt.ForeColor = SystemColors.HighlightText; lblRunningCnt.ForeColor = SystemColors.HotTrack;
lblRunningCnt.Location = new Point(0, 56); lblRunningCnt.Location = new Point(0, 56);
lblRunningCnt.Name = "lblRunningCnt"; lblRunningCnt.Name = "lblRunningCnt";
lblRunningCnt.Size = new Size(190, 48); lblRunningCnt.Size = new Size(190, 48);
@@ -115,6 +116,8 @@
// //
// lblBlueTitle // lblBlueTitle
// //
lblBlueTitle.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblBlueTitle.ForeColor = SystemColors.ControlDarkDark;
lblBlueTitle.Location = new Point(0, 20); lblBlueTitle.Location = new Point(0, 20);
lblBlueTitle.Name = "lblBlueTitle"; lblBlueTitle.Name = "lblBlueTitle";
lblBlueTitle.Size = new Size(190, 20); lblBlueTitle.Size = new Size(190, 20);
@@ -134,7 +137,7 @@
grdTotList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; grdTotList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
grdTotList.ColumnHeadersHeight = 29; grdTotList.ColumnHeadersHeight = 29;
grdTotList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; grdTotList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
grdTotList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col8 }); grdTotList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col8, Col9, Col10, Col11 });
dataGridViewCellStyle8.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle8.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle8.BackColor = SystemColors.Window; dataGridViewCellStyle8.BackColor = SystemColors.Window;
dataGridViewCellStyle8.Font = new Font("맑은 고딕", 9F); dataGridViewCellStyle8.Font = new Font("맑은 고딕", 9F);
@@ -148,61 +151,61 @@
grdTotList.RowHeadersWidth = 51; grdTotList.RowHeadersWidth = 51;
grdTotList.Size = new Size(1000, 417); grdTotList.Size = new Size(1000, 417);
grdTotList.TabIndex = 3; grdTotList.TabIndex = 3;
grdTotList.CellMouseClick += grdTotList_CellMouseClick; grdTotList.CellContentClick += grdTotList_CellContentClick;
//
// btnLog
//
btnLog.Location = new Point(1009, 244);
btnLog.Name = "btnLog";
btnLog.Size = new Size(150, 44);
btnLog.TabIndex = 4;
btnLog.Text = "제어 이력 조회";
btnLog.UseVisualStyleBackColor = true;
btnLog.MouseClick += btnLog_MouseClick;
// //
// btnRegister // btnRegister
// //
btnRegister.Location = new Point(880, 244); btnRegister.BackColor = Color.RoyalBlue;
btnRegister.ForeColor = SystemColors.HighlightText;
btnRegister.Image = Properties.Resources.imgDataRegister;
btnRegister.ImageAlign = ContentAlignment.MiddleLeft;
btnRegister.Location = new Point(1029, 242);
btnRegister.Name = "btnRegister"; btnRegister.Name = "btnRegister";
btnRegister.Size = new Size(123, 44); btnRegister.Size = new Size(130, 50);
btnRegister.TabIndex = 5; btnRegister.TabIndex = 5;
btnRegister.Text = "단말기 등록"; btnRegister.Text = "단말기 등록";
btnRegister.UseVisualStyleBackColor = true; btnRegister.TextAlign = ContentAlignment.MiddleRight;
btnRegister.UseVisualStyleBackColor = false;
btnRegister.MouseClick += btnRegister_MouseClick; btnRegister.MouseClick += btnRegister_MouseClick;
// //
// btnDataUpdate // btnDataUpdate
// //
btnDataUpdate.Location = new Point(750, 244); btnDataUpdate.Image = Properties.Resources.imgDataUpdate;
btnDataUpdate.ImageAlign = ContentAlignment.MiddleLeft;
btnDataUpdate.Location = new Point(893, 242);
btnDataUpdate.Name = "btnDataUpdate"; btnDataUpdate.Name = "btnDataUpdate";
btnDataUpdate.Size = new Size(123, 44); btnDataUpdate.Size = new Size(130, 50);
btnDataUpdate.TabIndex = 6; btnDataUpdate.TabIndex = 6;
btnDataUpdate.Text = "데이터 갱신"; btnDataUpdate.Text = "데이터 갱신";
btnDataUpdate.TextAlign = ContentAlignment.MiddleRight;
btnDataUpdate.UseVisualStyleBackColor = true; btnDataUpdate.UseVisualStyleBackColor = true;
btnDataUpdate.MouseClick += btnDataUpdate_MouseClick; btnDataUpdate.Click += btnDataUpdate_Click;
// //
// txtSearch // txtSearch
// //
txtSearch.Font = new Font("맑은 고딕", 12F, FontStyle.Regular, GraphicsUnit.Point, 129);
txtSearch.Location = new Point(159, 244); txtSearch.Location = new Point(159, 244);
txtSearch.Multiline = true; txtSearch.Multiline = true;
txtSearch.Name = "txtSearch"; txtSearch.Name = "txtSearch";
txtSearch.Size = new Size(256, 44); txtSearch.Size = new Size(256, 44);
txtSearch.TabIndex = 7; txtSearch.TabIndex = 7;
txtSearch.TextAlign = HorizontalAlignment.Center; txtSearch.TextAlign = HorizontalAlignment.Center;
txtSearch.TextChanged += txtSearch_TextChanged;
// //
// pictureBox1 // imgSearch
// //
pictureBox1.Image = Properties.Resources.button_search; imgSearch.Image = Properties.Resources.button_search;
pictureBox1.Location = new Point(430, 244); imgSearch.Location = new Point(430, 244);
pictureBox1.Name = "pictureBox1"; imgSearch.Name = "imgSearch";
pictureBox1.Size = new Size(44, 44); imgSearch.Size = new Size(44, 44);
pictureBox1.TabIndex = 8; imgSearch.TabIndex = 8;
pictureBox1.TabStop = false; imgSearch.TabStop = false;
imgSearch.MouseClick += imgSearch_MouseClick;
// //
// Col0 // Col0
// //
dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col0.DefaultCellStyle = dataGridViewCellStyle2; Col0.DefaultCellStyle = dataGridViewCellStyle2;
Col0.Frozen = true;
Col0.HeaderText = "단말기명"; Col0.HeaderText = "단말기명";
Col0.MinimumWidth = 6; Col0.MinimumWidth = 6;
Col0.Name = "Col0"; Col0.Name = "Col0";
@@ -212,7 +215,6 @@
// //
dataGridViewCellStyle3.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle3.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col1.DefaultCellStyle = dataGridViewCellStyle3; Col1.DefaultCellStyle = dataGridViewCellStyle3;
Col1.Frozen = true;
Col1.HeaderText = "MAC주소"; Col1.HeaderText = "MAC주소";
Col1.MinimumWidth = 6; Col1.MinimumWidth = 6;
Col1.Name = "Col1"; Col1.Name = "Col1";
@@ -222,7 +224,6 @@
// //
dataGridViewCellStyle4.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle4.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col2.DefaultCellStyle = dataGridViewCellStyle4; Col2.DefaultCellStyle = dataGridViewCellStyle4;
Col2.Frozen = true;
Col2.HeaderText = "IP"; Col2.HeaderText = "IP";
Col2.MinimumWidth = 6; Col2.MinimumWidth = 6;
Col2.Name = "Col2"; Col2.Name = "Col2";
@@ -232,7 +233,6 @@
// //
dataGridViewCellStyle5.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle5.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col3.DefaultCellStyle = dataGridViewCellStyle5; Col3.DefaultCellStyle = dataGridViewCellStyle5;
Col3.Frozen = true;
Col3.HeaderText = "통신설정"; Col3.HeaderText = "통신설정";
Col3.MinimumWidth = 6; Col3.MinimumWidth = 6;
Col3.Name = "Col3"; Col3.Name = "Col3";
@@ -242,7 +242,6 @@
// //
dataGridViewCellStyle6.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle6.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col4.DefaultCellStyle = dataGridViewCellStyle6; Col4.DefaultCellStyle = dataGridViewCellStyle6;
Col4.Frozen = true;
Col4.HeaderText = "프로그램"; Col4.HeaderText = "프로그램";
Col4.MinimumWidth = 6; Col4.MinimumWidth = 6;
Col4.Name = "Col4"; Col4.Name = "Col4";
@@ -252,7 +251,6 @@
// //
dataGridViewCellStyle7.Alignment = DataGridViewContentAlignment.MiddleCenter; dataGridViewCellStyle7.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col5.DefaultCellStyle = dataGridViewCellStyle7; Col5.DefaultCellStyle = dataGridViewCellStyle7;
Col5.Frozen = true;
Col5.HeaderText = "마지막 통신 시간"; Col5.HeaderText = "마지막 통신 시간";
Col5.MinimumWidth = 6; Col5.MinimumWidth = 6;
Col5.Name = "Col5"; Col5.Name = "Col5";
@@ -267,44 +265,71 @@
Col8.Visible = false; Col8.Visible = false;
Col8.Width = 125; Col8.Width = 125;
// //
// Col9
//
Col9.HeaderText = "표출시간";
Col9.MinimumWidth = 6;
Col9.Name = "Col9";
Col9.ReadOnly = true;
Col9.Visible = false;
Col9.Width = 125;
//
// Col10
//
Col10.HeaderText = "프로그램ON시간";
Col10.MinimumWidth = 6;
Col10.Name = "Col10";
Col10.ReadOnly = true;
Col10.Visible = false;
Col10.Width = 125;
//
// Col11
//
Col11.HeaderText = "프로그램OFF시간";
Col11.MinimumWidth = 6;
Col11.Name = "Col11";
Col11.ReadOnly = true;
Col11.Visible = false;
Col11.Width = 125;
//
// Form1 // Form1
// //
AutoScaleDimensions = new SizeF(9F, 20F); AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1357, 737); ClientSize = new Size(1357, 737);
Controls.Add(pictureBox1); Controls.Add(imgSearch);
Controls.Add(txtSearch); Controls.Add(txtSearch);
Controls.Add(btnDataUpdate); Controls.Add(btnDataUpdate);
Controls.Add(btnRegister); Controls.Add(btnRegister);
Controls.Add(btnLog);
Controls.Add(grdTotList); Controls.Add(grdTotList);
Controls.Add(pannBlue); Controls.Add(pannBlue);
Controls.Add(pannGray); Controls.Add(pannGray);
Name = "Form1"; Name = "Form1";
Text = "Form1"; Text = "Form1";
Load += Form1_Load_1;
pannGray.ResumeLayout(false); pannGray.ResumeLayout(false);
pannGray.PerformLayout();
pannBlue.ResumeLayout(false); pannBlue.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)grdTotList).EndInit(); ((System.ComponentModel.ISupportInitialize)grdTotList).EndInit();
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ((System.ComponentModel.ISupportInitialize)imgSearch).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
} }
#endregion #endregion
private Panel pannGray; //private Panel pannGray;
private Panel pannBlue; //private Panel pannBlue;
private RoundedPanel pannGray;
private RoundedPanel pannBlue;
private Label lblGrayTitle; private Label lblGrayTitle;
private Label lblBlueTitle; private Label lblBlueTitle;
private Label lblTotCnt; private Label lblTotCnt;
private Label lblRunningCnt; private Label lblRunningCnt;
private DataGridView grdTotList; private DataGridView grdTotList;
private Button btnLog;
private Button btnRegister; private Button btnRegister;
private Button btnDataUpdate; private Button btnDataUpdate;
private TextBox txtSearch; private TextBox txtSearch;
private PictureBox pictureBox1; private PictureBox imgSearch;
private DataGridViewTextBoxColumn Col0; private DataGridViewTextBoxColumn Col0;
private DataGridViewTextBoxColumn Col1; private DataGridViewTextBoxColumn Col1;
private DataGridViewTextBoxColumn Col2; private DataGridViewTextBoxColumn Col2;
@@ -312,5 +337,8 @@
private DataGridViewTextBoxColumn Col4; private DataGridViewTextBoxColumn Col4;
private DataGridViewTextBoxColumn Col5; private DataGridViewTextBoxColumn Col5;
private DataGridViewTextBoxColumn Col8; private DataGridViewTextBoxColumn Col8;
private DataGridViewTextBoxColumn Col9;
private DataGridViewTextBoxColumn Col10;
private DataGridViewTextBoxColumn Col11;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -138,4 +138,13 @@
<metadata name="Col8.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Col8.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Col9.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col10.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col11.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

View File

@@ -36,52 +36,54 @@
btnCancel = new Button(); btnCancel = new Button();
txtBoxPort = new TextBox(); txtBoxPort = new TextBox();
lbl5 = new Label(); lbl5 = new Label();
txtBoxMac = new TextBox();
lbl2 = new Label();
lblTitle = new Label();
lblBox = new Label();
SuspendLayout(); SuspendLayout();
// //
// lbl0 // lbl0
// //
lbl0.BackColor = SystemColors.ControlDark; lbl0.BackColor = Color.White;
lbl0.BorderStyle = BorderStyle.FixedSingle; lbl0.Location = new Point(195, 116);
lbl0.Location = new Point(277, 106);
lbl0.Name = "lbl0"; lbl0.Name = "lbl0";
lbl0.Size = new Size(293, 50); lbl0.Size = new Size(270, 50);
lbl0.TabIndex = 0; lbl0.TabIndex = 0;
lbl0.Text = "단말기명"; lbl0.Text = "단말기명";
lbl0.TextAlign = ContentAlignment.MiddleLeft; lbl0.TextAlign = ContentAlignment.MiddleLeft;
// //
// lbl1 // lbl1
// //
lbl1.BackColor = SystemColors.ControlDark; lbl1.BackColor = Color.White;
lbl1.BorderStyle = BorderStyle.FixedSingle; lbl1.Location = new Point(195, 166);
lbl1.Location = new Point(277, 156);
lbl1.Name = "lbl1"; lbl1.Name = "lbl1";
lbl1.Size = new Size(293, 50); lbl1.Size = new Size(270, 50);
lbl1.TabIndex = 1; lbl1.TabIndex = 1;
lbl1.Text = "IP"; lbl1.Text = "IP";
lbl1.TextAlign = ContentAlignment.MiddleLeft; lbl1.TextAlign = ContentAlignment.MiddleLeft;
// //
// txtBoxName // txtBoxName
// //
txtBoxName.Location = new Point(572, 106); txtBoxName.Location = new Point(471, 127);
txtBoxName.Multiline = true; txtBoxName.Multiline = true;
txtBoxName.Name = "txtBoxName"; txtBoxName.Name = "txtBoxName";
txtBoxName.Size = new Size(507, 50); txtBoxName.Size = new Size(350, 32);
txtBoxName.TabIndex = 4; txtBoxName.TabIndex = 4;
// //
// txtBoxIP // txtBoxIP
// //
txtBoxIP.Location = new Point(572, 156); txtBoxIP.Location = new Point(471, 177);
txtBoxIP.Multiline = true; txtBoxIP.Multiline = true;
txtBoxIP.Name = "txtBoxIP"; txtBoxIP.Name = "txtBoxIP";
txtBoxIP.Size = new Size(507, 50); txtBoxIP.Size = new Size(350, 32);
txtBoxIP.TabIndex = 5; txtBoxIP.TabIndex = 5;
// //
// btnRegister // btnRegister
// //
btnRegister.BackColor = SystemColors.Desktop; btnRegister.BackColor = Color.RoyalBlue;
btnRegister.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); btnRegister.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
btnRegister.ForeColor = SystemColors.Window; btnRegister.ForeColor = SystemColors.Window;
btnRegister.Location = new Point(460, 291); btnRegister.Location = new Point(296, 366);
btnRegister.Name = "btnRegister"; btnRegister.Name = "btnRegister";
btnRegister.Size = new Size(174, 56); btnRegister.Size = new Size(174, 56);
btnRegister.TabIndex = 9; btnRegister.TabIndex = 9;
@@ -92,7 +94,7 @@
// btnCancel // btnCancel
// //
btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
btnCancel.Location = new Point(710, 291); btnCancel.Location = new Point(535, 366);
btnCancel.Name = "btnCancel"; btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(174, 56); btnCancel.Size = new Size(174, 56);
btnCancel.TabIndex = 10; btnCancel.TabIndex = 10;
@@ -102,28 +104,67 @@
// //
// txtBoxPort // txtBoxPort
// //
txtBoxPort.Location = new Point(572, 206); txtBoxPort.Location = new Point(471, 227);
txtBoxPort.Multiline = true; txtBoxPort.Multiline = true;
txtBoxPort.Name = "txtBoxPort"; txtBoxPort.Name = "txtBoxPort";
txtBoxPort.Size = new Size(507, 50); txtBoxPort.Size = new Size(350, 32);
txtBoxPort.TabIndex = 12; txtBoxPort.TabIndex = 12;
// //
// lbl5 // lbl5
// //
lbl5.BackColor = SystemColors.ControlDark; lbl5.BackColor = Color.White;
lbl5.BorderStyle = BorderStyle.FixedSingle; lbl5.Location = new Point(195, 216);
lbl5.Location = new Point(277, 206);
lbl5.Name = "lbl5"; lbl5.Name = "lbl5";
lbl5.Size = new Size(293, 50); lbl5.Size = new Size(270, 50);
lbl5.TabIndex = 11; lbl5.TabIndex = 11;
lbl5.Text = "Port"; lbl5.Text = "Port";
lbl5.TextAlign = ContentAlignment.MiddleLeft; lbl5.TextAlign = ContentAlignment.MiddleLeft;
// //
// txtBoxMac
//
txtBoxMac.Location = new Point(471, 276);
txtBoxMac.Multiline = true;
txtBoxMac.Name = "txtBoxMac";
txtBoxMac.Size = new Size(350, 32);
txtBoxMac.TabIndex = 14;
//
// lbl2
//
lbl2.BackColor = Color.White;
lbl2.Location = new Point(195, 266);
lbl2.Name = "lbl2";
lbl2.Size = new Size(270, 50);
lbl2.TabIndex = 13;
lbl2.Text = "MAC";
lbl2.TextAlign = ContentAlignment.MiddleLeft;
//
// lblTitle
//
lblTitle.AutoSize = true;
lblTitle.BackColor = Color.White;
lblTitle.Font = new Font("맑은 고딕", 18F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTitle.Location = new Point(92, 34);
lblTitle.Name = "lblTitle";
lblTitle.Size = new Size(179, 41);
lblTitle.TabIndex = 15;
lblTitle.Text = "단말기 등록";
//
// lblBox
//
lblBox.BackColor = Color.White;
lblBox.Location = new Point(56, 23);
lblBox.Name = "lblBox";
lblBox.Size = new Size(953, 306);
lblBox.TabIndex = 16;
//
// Form2 // Form2
// //
AutoScaleDimensions = new SizeF(9F, 20F); AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1357, 737); ClientSize = new Size(1070, 461);
Controls.Add(lblTitle);
Controls.Add(txtBoxMac);
Controls.Add(lbl2);
Controls.Add(txtBoxPort); Controls.Add(txtBoxPort);
Controls.Add(lbl5); Controls.Add(lbl5);
Controls.Add(btnCancel); Controls.Add(btnCancel);
@@ -132,6 +173,7 @@
Controls.Add(txtBoxName); Controls.Add(txtBoxName);
Controls.Add(lbl1); Controls.Add(lbl1);
Controls.Add(lbl0); Controls.Add(lbl0);
Controls.Add(lblBox);
Name = "Form2"; Name = "Form2";
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
@@ -147,5 +189,9 @@
private Button btnCancel; private Button btnCancel;
private TextBox txtBoxPort; private TextBox txtBoxPort;
private Label lbl5; private Label lbl5;
private TextBox txtBoxMac;
private Label lbl2;
private Label lblTitle;
private Label lblBox;
} }
} }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
@@ -12,31 +13,106 @@ namespace ControlServer
{ {
public TerminalInfo TerminalData { get; private set; } = new TerminalInfo(); public TerminalInfo TerminalData { get; private set; } = new TerminalInfo();
// 둥근 모서리 반지름 설정
private const int CornerRadius = 15;
public Form2() public Form2()
{ {
InitializeComponent(); InitializeComponent();
// 1. 버튼 테두리 없애고 Flat 스타일로 변경
ConfigureModernButtons();
btnRegister.BackColor = Color.FromArgb(160, 180, 240); // 연해진 블루
btnRegister.Enabled = false; // 저장버튼 비활성화 btnRegister.Enabled = false; // 저장버튼 비활성화
// 모든 텍스트박스의 값이 변할 때마다 실행될 이벤트 연결 // 모든 텍스트박스의 값이 변할 때마다 실행될 이벤트 연결
txtBoxName.TextChanged += ValidateInputs; txtBoxName.TextChanged += ValidateInputs;
txtBoxIP.TextChanged += ValidateInputs; txtBoxIP.TextChanged += ValidateInputs;
txtBoxPort.TextChanged += ValidateInputs; txtBoxPort.TextChanged += ValidateInputs;
txtBoxMac.TextChanged += ValidateInputs;
// 2. 둥근 모서리를 그리기 위한 Paint 이벤트 연결
if (lblBox != null) lblBox.Paint += lblBox_Paint;
btnRegister.Paint += Button_Paint;
btnCancel.Paint += Button_Paint;
}
private void ConfigureModernButtons()
{
// 등록 버튼 스타일 설정
btnRegister.FlatStyle = FlatStyle.Flat;
btnRegister.FlatAppearance.BorderSize = 0; // 보더라인 삭제
// 취소 버튼 스타일 설정
btnCancel.BackColor = Color.FromArgb(230, 235, 240);
btnCancel.FlatStyle = FlatStyle.Flat;
btnCancel.FlatAppearance.BorderSize = 0; // 보더라인 삭제
}
// 컨트롤을 둥글게 만들기 위한 공통 경로 생성 메서드
private GraphicsPath GetRoundPath(Rectangle bounds, int radius)
{
GraphicsPath path = new GraphicsPath();
int diameter = radius * 2;
path.AddArc(bounds.X, bounds.Y, diameter, diameter, 180, 90);
path.AddArc(bounds.Right - diameter, bounds.Y, diameter, diameter, 270, 90);
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
path.AddArc(bounds.X, bounds.Bottom - diameter, diameter, diameter, 90, 90);
path.CloseAllFigures();
return path;
}
// 흰색 배경 박스 둥글게 자르기
private void lblBox_Paint(object? sender, PaintEventArgs e)
{
if (sender is Panel panel)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, panel.Width, panel.Height), CornerRadius))
{
panel.Region = new Region(path);
}
}
}
// 버튼 둥글게 자르기
private void Button_Paint(object? sender, PaintEventArgs e)
{
if (sender is Button button)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
// 버튼은 박스보다 조금 더 작으므로 반지름을 10 정도로 주면 예쁩니다
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, button.Width, button.Height), 10))
{
button.Region = new Region(path);
}
}
} }
private void ValidateInputs(object? sender, EventArgs e) private void ValidateInputs(object? sender, EventArgs e)
{ {
// 모든 텍스트박스가 공백이 아닐 때만 true
bool isValid = !string.IsNullOrWhiteSpace(txtBoxName.Text) && bool isValid = !string.IsNullOrWhiteSpace(txtBoxName.Text) &&
!string.IsNullOrWhiteSpace(txtBoxIP.Text) && !string.IsNullOrWhiteSpace(txtBoxIP.Text) &&
!string.IsNullOrWhiteSpace(txtBoxPort.Text); !string.IsNullOrWhiteSpace(txtBoxPort.Text) &&
!string.IsNullOrWhiteSpace(txtBoxMac.Text);
// 저장 버튼 활성화 상태 조절
btnRegister.Enabled = isValid; btnRegister.Enabled = isValid;
// [팁] 비활성화 상태일 때 버튼 색상 피드백을 주면 더 자연스럽습니다.
if (isValid)
{
btnRegister.BackColor = Color.FromArgb(65, 105, 225); // 원래 로열 블루 색상
}
else
{
btnRegister.BackColor = Color.FromArgb(160, 180, 240); // 연해진 블루
}
} }
private void btnCancel_MouseClick(object sender, MouseEventArgs e) private void btnCancel_MouseClick(object sender, MouseEventArgs e)
{ {
// 취소 버튼
this.Close(); this.Close();
} }
@@ -44,17 +120,23 @@ namespace ControlServer
{ {
// 1. DB 중복 데이터 확인 // 1. DB 중복 데이터 확인
// 2. 중복 데이터 없을 경우 DB에 데이터 추가 // 2. 메시지박스 띄우기 (알림 아이콘과 OK 버튼 포함)
// DB 가져오면 데이터 넘겨주는게 아니라 테이블에 데이터 추가하고 Form1 화면에서 데이터 가져와 리스트 보여주는 형식으로 변경할 예정 DialogResult result = MessageBox.Show(
Popup popup = new Popup("등록되었습니다."); "등록되었습니다.",
"알림",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
if (popup.ShowDialog() == DialogResult.OK) // 사용자가 메시지박스의 '확인'을 누르면 데이터 저장 진행
if (result == DialogResult.OK)
{ {
this.TerminalData = new TerminalInfo this.TerminalData = new TerminalInfo
{ {
TerminalName = txtBoxName.Text.Trim(), TerminalName = txtBoxName.Text.Trim(),
IP = txtBoxIP.Text.Trim(), IP = txtBoxIP.Text.Trim(),
Port = txtBoxPort.Text.Trim() Port = txtBoxPort.Text.Trim(),
Mac = txtBoxMac.Text.Trim(),
}; };
} }

View File

@@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle();
lblTerminalName = new Label(); lblTerminalName = new Label();
lblTerminalIP = new Label(); lblTerminalIP = new Label();
label1 = new Label(); label1 = new Label();
@@ -36,28 +37,42 @@
label3 = new Label(); label3 = new Label();
label4 = new Label(); label4 = new Label();
pannUpdate = new Panel(); pannUpdate = new Panel();
rdoUpdate5m = new RadioButton(); label7 = new Label();
rdoUpdate3m = new RadioButton(); txtBoxDisplay = new TextBox();
rdoUpdate1m = new RadioButton();
pannStartTime = new Panel(); pannStartTime = new Panel();
label8 = new Label();
txtBoxOnSS = new TextBox();
label5 = new Label(); label5 = new Label();
txtBoxOnMM = new TextBox(); txtBoxOnMM = new TextBox();
txtBoxOnYY = new TextBox(); txtBoxOnYY = new TextBox();
pannStopTime = new Panel(); pannStopTime = new Panel();
label9 = new Label();
txtBoxOffSS = new TextBox();
label6 = new Label(); label6 = new Label();
txtBoxOffMM = new TextBox(); txtBoxOffMM = new TextBox();
txtBoxOffYY = new TextBox(); txtBoxOffYY = new TextBox();
btnCancel = new Button(); btnCancel = new Button();
btnUpdate = new Button(); btnUpdate = new Button();
grdDataList = new DataGridView();
lblBox = new Label();
Col0 = new DataGridViewTextBoxColumn();
Col1 = new DataGridViewTextBoxColumn();
Col2 = new DataGridViewTextBoxColumn();
Col3 = new DataGridViewTextBoxColumn();
Col4 = new DataGridViewTextBoxColumn();
Col5 = new DataGridViewTextBoxColumn();
Col6 = new DataGridViewTextBoxColumn();
pannUpdate.SuspendLayout(); pannUpdate.SuspendLayout();
pannStartTime.SuspendLayout(); pannStartTime.SuspendLayout();
pannStopTime.SuspendLayout(); pannStopTime.SuspendLayout();
((System.ComponentModel.ISupportInitialize)grdDataList).BeginInit();
SuspendLayout(); SuspendLayout();
// //
// lblTerminalName // lblTerminalName
// //
lblTerminalName.BackColor = Color.White;
lblTerminalName.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129); lblTerminalName.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129);
lblTerminalName.Location = new Point(430, 42); lblTerminalName.Location = new Point(256, 102);
lblTerminalName.Name = "lblTerminalName"; lblTerminalName.Name = "lblTerminalName";
lblTerminalName.Size = new Size(288, 50); lblTerminalName.Size = new Size(288, 50);
lblTerminalName.TabIndex = 0; lblTerminalName.TabIndex = 0;
@@ -65,7 +80,8 @@
// //
// lblTerminalIP // lblTerminalIP
// //
lblTerminalIP.Location = new Point(430, 118); lblTerminalIP.BackColor = Color.White;
lblTerminalIP.Location = new Point(256, 178);
lblTerminalIP.Name = "lblTerminalIP"; lblTerminalIP.Name = "lblTerminalIP";
lblTerminalIP.Size = new Size(288, 50); lblTerminalIP.Size = new Size(288, 50);
lblTerminalIP.TabIndex = 1; lblTerminalIP.TabIndex = 1;
@@ -73,7 +89,8 @@
// //
// label1 // label1
// //
label1.Location = new Point(254, 42); label1.BackColor = Color.White;
label1.Location = new Point(103, 102);
label1.Name = "label1"; label1.Name = "label1";
label1.Size = new Size(147, 50); label1.Size = new Size(147, 50);
label1.TabIndex = 2; label1.TabIndex = 2;
@@ -82,7 +99,8 @@
// //
// label2 // label2
// //
label2.Location = new Point(254, 118); label2.BackColor = Color.White;
label2.Location = new Point(103, 178);
label2.Name = "label2"; label2.Name = "label2";
label2.Size = new Size(147, 50); label2.Size = new Size(147, 50);
label2.TabIndex = 3; label2.TabIndex = 3;
@@ -91,20 +109,18 @@
// //
// lbl0 // lbl0
// //
lbl0.BackColor = SystemColors.ControlDark; lbl0.BackColor = Color.White;
lbl0.BorderStyle = BorderStyle.FixedSingle; lbl0.Location = new Point(97, 285);
lbl0.Location = new Point(254, 223);
lbl0.Name = "lbl0"; lbl0.Name = "lbl0";
lbl0.Size = new Size(159, 50); lbl0.Size = new Size(159, 50);
lbl0.TabIndex = 4; lbl0.TabIndex = 4;
lbl0.Text = "갱신주기"; lbl0.Text = "표출시간";
lbl0.TextAlign = ContentAlignment.MiddleLeft; lbl0.TextAlign = ContentAlignment.MiddleLeft;
// //
// label3 // label3
// //
label3.BackColor = SystemColors.ControlDark; label3.BackColor = Color.White;
label3.BorderStyle = BorderStyle.FixedSingle; label3.Location = new Point(97, 335);
label3.Location = new Point(254, 273);
label3.Name = "label3"; label3.Name = "label3";
label3.Size = new Size(159, 50); label3.Size = new Size(159, 50);
label3.TabIndex = 5; label3.TabIndex = 5;
@@ -113,9 +129,8 @@
// //
// label4 // label4
// //
label4.BackColor = SystemColors.ControlDark; label4.BackColor = Color.White;
label4.BorderStyle = BorderStyle.FixedSingle; label4.Location = new Point(97, 385);
label4.Location = new Point(254, 323);
label4.Name = "label4"; label4.Name = "label4";
label4.Size = new Size(159, 50); label4.Size = new Size(159, 50);
label4.TabIndex = 6; label4.TabIndex = 6;
@@ -124,59 +139,61 @@
// //
// pannUpdate // pannUpdate
// //
pannUpdate.BorderStyle = BorderStyle.FixedSingle; pannUpdate.BackColor = Color.White;
pannUpdate.Controls.Add(rdoUpdate5m); pannUpdate.Controls.Add(label7);
pannUpdate.Controls.Add(rdoUpdate3m); pannUpdate.Controls.Add(txtBoxDisplay);
pannUpdate.Controls.Add(rdoUpdate1m); pannUpdate.Location = new Point(256, 285);
pannUpdate.Location = new Point(413, 223);
pannUpdate.Name = "pannUpdate"; pannUpdate.Name = "pannUpdate";
pannUpdate.Size = new Size(356, 50); pannUpdate.Size = new Size(356, 50);
pannUpdate.TabIndex = 7; pannUpdate.TabIndex = 7;
// //
// rdoUpdate5m // label7
// //
rdoUpdate5m.AutoSize = true; label7.AutoSize = true;
rdoUpdate5m.Location = new Point(157, 12); label7.Location = new Point(86, 14);
rdoUpdate5m.Name = "rdoUpdate5m"; label7.Name = "label7";
rdoUpdate5m.Size = new Size(53, 24); label7.Size = new Size(24, 20);
rdoUpdate5m.TabIndex = 2; label7.TabIndex = 1;
rdoUpdate5m.TabStop = true; label7.Text = "초";
rdoUpdate5m.Text = "5분";
rdoUpdate5m.UseVisualStyleBackColor = true;
// //
// rdoUpdate3m // txtBoxDisplay
// //
rdoUpdate3m.AutoSize = true; txtBoxDisplay.Location = new Point(16, 11);
rdoUpdate3m.Location = new Point(86, 12); txtBoxDisplay.Name = "txtBoxDisplay";
rdoUpdate3m.Name = "rdoUpdate3m"; txtBoxDisplay.Size = new Size(64, 27);
rdoUpdate3m.Size = new Size(53, 24); txtBoxDisplay.TabIndex = 0;
rdoUpdate3m.TabIndex = 1; txtBoxDisplay.Text = "5";
rdoUpdate3m.TabStop = true;
rdoUpdate3m.Text = "3분";
rdoUpdate3m.UseVisualStyleBackColor = true;
//
// rdoUpdate1m
//
rdoUpdate1m.AutoSize = true;
rdoUpdate1m.Location = new Point(16, 12);
rdoUpdate1m.Name = "rdoUpdate1m";
rdoUpdate1m.Size = new Size(53, 24);
rdoUpdate1m.TabIndex = 0;
rdoUpdate1m.TabStop = true;
rdoUpdate1m.Text = "1분";
rdoUpdate1m.UseVisualStyleBackColor = true;
// //
// pannStartTime // pannStartTime
// //
pannStartTime.BorderStyle = BorderStyle.FixedSingle; pannStartTime.BackColor = Color.White;
pannStartTime.Controls.Add(label8);
pannStartTime.Controls.Add(txtBoxOnSS);
pannStartTime.Controls.Add(label5); pannStartTime.Controls.Add(label5);
pannStartTime.Controls.Add(txtBoxOnMM); pannStartTime.Controls.Add(txtBoxOnMM);
pannStartTime.Controls.Add(txtBoxOnYY); pannStartTime.Controls.Add(txtBoxOnYY);
pannStartTime.Location = new Point(413, 273); pannStartTime.Location = new Point(256, 335);
pannStartTime.Name = "pannStartTime"; pannStartTime.Name = "pannStartTime";
pannStartTime.Size = new Size(356, 50); pannStartTime.Size = new Size(356, 50);
pannStartTime.TabIndex = 8; pannStartTime.TabIndex = 8;
// //
// label8
//
label8.AutoSize = true;
label8.Location = new Point(171, 14);
label8.Name = "label8";
label8.Size = new Size(12, 20);
label8.TabIndex = 4;
label8.Text = ":";
//
// txtBoxOnSS
//
txtBoxOnSS.Location = new Point(185, 11);
txtBoxOnSS.Name = "txtBoxOnSS";
txtBoxOnSS.Size = new Size(64, 27);
txtBoxOnSS.TabIndex = 3;
txtBoxOnSS.TextAlign = HorizontalAlignment.Center;
//
// label5 // label5
// //
label5.AutoSize = true; label5.AutoSize = true;
@@ -204,15 +221,34 @@
// //
// pannStopTime // pannStopTime
// //
pannStopTime.BorderStyle = BorderStyle.FixedSingle; pannStopTime.BackColor = Color.White;
pannStopTime.Controls.Add(label9);
pannStopTime.Controls.Add(txtBoxOffSS);
pannStopTime.Controls.Add(label6); pannStopTime.Controls.Add(label6);
pannStopTime.Controls.Add(txtBoxOffMM); pannStopTime.Controls.Add(txtBoxOffMM);
pannStopTime.Controls.Add(txtBoxOffYY); pannStopTime.Controls.Add(txtBoxOffYY);
pannStopTime.Location = new Point(413, 323); pannStopTime.Location = new Point(256, 385);
pannStopTime.Name = "pannStopTime"; pannStopTime.Name = "pannStopTime";
pannStopTime.Size = new Size(356, 50); pannStopTime.Size = new Size(356, 50);
pannStopTime.TabIndex = 9; pannStopTime.TabIndex = 9;
// //
// label9
//
label9.AutoSize = true;
label9.Location = new Point(169, 14);
label9.Name = "label9";
label9.Size = new Size(12, 20);
label9.TabIndex = 7;
label9.Text = ":";
//
// txtBoxOffSS
//
txtBoxOffSS.Location = new Point(185, 11);
txtBoxOffSS.Name = "txtBoxOffSS";
txtBoxOffSS.Size = new Size(64, 27);
txtBoxOffSS.TabIndex = 6;
txtBoxOffSS.TextAlign = HorizontalAlignment.Center;
//
// label6 // label6
// //
label6.AutoSize = true; label6.AutoSize = true;
@@ -241,7 +277,7 @@
// btnCancel // btnCancel
// //
btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
btnCancel.Location = new Point(559, 408); btnCancel.Location = new Point(386, 497);
btnCancel.Name = "btnCancel"; btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(174, 56); btnCancel.Size = new Size(174, 56);
btnCancel.TabIndex = 12; btnCancel.TabIndex = 12;
@@ -251,10 +287,10 @@
// //
// btnUpdate // btnUpdate
// //
btnUpdate.BackColor = SystemColors.Desktop; btnUpdate.BackColor = Color.RoyalBlue;
btnUpdate.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); btnUpdate.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
btnUpdate.ForeColor = SystemColors.Window; btnUpdate.ForeColor = SystemColors.Window;
btnUpdate.Location = new Point(309, 408); btnUpdate.Location = new Point(136, 497);
btnUpdate.Name = "btnUpdate"; btnUpdate.Name = "btnUpdate";
btnUpdate.Size = new Size(174, 56); btnUpdate.Size = new Size(174, 56);
btnUpdate.TabIndex = 11; btnUpdate.TabIndex = 11;
@@ -262,11 +298,92 @@
btnUpdate.UseVisualStyleBackColor = false; btnUpdate.UseVisualStyleBackColor = false;
btnUpdate.MouseClick += btnUpdate_MouseClick; btnUpdate.MouseClick += btnUpdate_MouseClick;
// //
// grdDataList
//
dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = SystemColors.Control;
dataGridViewCellStyle1.Font = new Font("맑은 고딕", 7.8F, FontStyle.Regular, GraphicsUnit.Point, 129);
dataGridViewCellStyle1.ForeColor = SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True;
grdDataList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
grdDataList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col6 });
grdDataList.Location = new Point(704, 46);
grdDataList.Name = "grdDataList";
grdDataList.RowHeadersWidth = 51;
grdDataList.Size = new Size(641, 679);
grdDataList.TabIndex = 13;
//
// lblBox
//
lblBox.BackColor = Color.White;
lblBox.Location = new Point(43, 46);
lblBox.Name = "lblBox";
lblBox.Size = new Size(597, 542);
lblBox.TabIndex = 14;
//
// Col0
//
Col0.HeaderText = "경매일자";
Col0.MinimumWidth = 6;
Col0.Name = "Col0";
Col0.ReadOnly = true;
Col0.Width = 125;
//
// Col1
//
Col1.HeaderText = "품목명";
Col1.MinimumWidth = 6;
Col1.Name = "Col1";
Col1.ReadOnly = true;
Col1.Width = 125;
//
// Col2
//
Col2.HeaderText = "산지";
Col2.MinimumWidth = 6;
Col2.Name = "Col2";
Col2.ReadOnly = true;
Col2.Width = 125;
//
// Col3
//
Col3.HeaderText = "전체수량";
Col3.MinimumWidth = 6;
Col3.Name = "Col3";
Col3.ReadOnly = true;
Col3.Width = 80;
//
// Col4
//
Col4.HeaderText = "정가수의 수량";
Col4.MinimumWidth = 6;
Col4.Name = "Col4";
Col4.ReadOnly = true;
//
// Col5
//
Col5.HeaderText = "전체물량";
Col5.MinimumWidth = 6;
Col5.Name = "Col5";
Col5.ReadOnly = true;
Col5.Width = 80;
//
// Col6
//
Col6.HeaderText = "정가수의 물량";
Col6.MinimumWidth = 6;
Col6.Name = "Col6";
Col6.ReadOnly = true;
//
// Form3 // Form3
// //
AutoScaleDimensions = new SizeF(9F, 20F); AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1008, 563); ClientSize = new Size(1357, 737);
Controls.Add(grdDataList);
Controls.Add(btnCancel); Controls.Add(btnCancel);
Controls.Add(btnUpdate); Controls.Add(btnUpdate);
Controls.Add(pannStopTime); Controls.Add(pannStopTime);
@@ -279,14 +396,16 @@
Controls.Add(label1); Controls.Add(label1);
Controls.Add(lblTerminalIP); Controls.Add(lblTerminalIP);
Controls.Add(lblTerminalName); Controls.Add(lblTerminalName);
Controls.Add(lblBox);
Name = "Form3"; Name = "Form3";
Text = "Form3"; Text = "S";
pannUpdate.ResumeLayout(false); pannUpdate.ResumeLayout(false);
pannUpdate.PerformLayout(); pannUpdate.PerformLayout();
pannStartTime.ResumeLayout(false); pannStartTime.ResumeLayout(false);
pannStartTime.PerformLayout(); pannStartTime.PerformLayout();
pannStopTime.ResumeLayout(false); pannStopTime.ResumeLayout(false);
pannStopTime.PerformLayout(); pannStopTime.PerformLayout();
((System.ComponentModel.ISupportInitialize)grdDataList).EndInit();
ResumeLayout(false); ResumeLayout(false);
} }
@@ -302,9 +421,6 @@
private Panel pannUpdate; private Panel pannUpdate;
private Panel pannStartTime; private Panel pannStartTime;
private Panel pannStopTime; private Panel pannStopTime;
private RadioButton rdoUpdate1m;
private RadioButton rdoUpdate5m;
private RadioButton rdoUpdate3m;
private TextBox txtBoxOnYY; private TextBox txtBoxOnYY;
private TextBox txtBoxOnMM; private TextBox txtBoxOnMM;
private Label label5; private Label label5;
@@ -313,5 +429,20 @@
private TextBox txtBoxOffYY; private TextBox txtBoxOffYY;
private Button btnCancel; private Button btnCancel;
private Button btnUpdate; private Button btnUpdate;
private TextBox txtBoxDisplay;
private Label label7;
private Label label8;
private TextBox txtBoxOnSS;
private Label label9;
private TextBox txtBoxOffSS;
private DataGridView grdDataList;
private Label lblBox;
private DataGridViewTextBoxColumn Col0;
private DataGridViewTextBoxColumn Col1;
private DataGridViewTextBoxColumn Col2;
private DataGridViewTextBoxColumn Col3;
private DataGridViewTextBoxColumn Col4;
private DataGridViewTextBoxColumn Col5;
private DataGridViewTextBoxColumn Col6;
} }
} }

View File

@@ -3,44 +3,220 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; // 둥근 모서리 그리기(GraphicsPath)에 필수
using System.IO;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using System.Xml.Linq;
namespace ControlServer namespace ControlServer
{ {
public partial class Form3 : Form public partial class Form3 : Form
{ {
public Form3(string terminalName, string terminalIP) // 매개변수 추가 private Form1 _mainForm; // 메인 폼 참조 변수
private string _targetIP;
private string _filePath;
// 둥근 모서리 반지름 설정 (정수형 int로 선언)
private const int CornerRadiusValue = 15;
public Form3(Form1 mainForm, string terminalName, string terminalIP, string filePath)
{ {
InitializeComponent(); InitializeComponent();
// 가져온 데이터를 Form3의 라벨이나 텍스트박스에 표시 // 1. 버튼 테두리 없애고 Flat 스타일 및 이벤트 연결
ConfigureModernStyles();
// 2. 그리드 디자인을 오른쪽 시안 스타일에 맞게 초기화
InitDataGridViewStyles();
_mainForm = mainForm;
_targetIP = terminalIP;
_filePath = filePath;
lblTerminalName.Text = terminalName; lblTerminalName.Text = terminalName;
lblTerminalIP.Text = terminalIP; lblTerminalIP.Text = terminalIP;
string[] timeData = _mainForm.GetProgramTimesByIp(_targetIP);
txtBoxDisplay.Text = string.IsNullOrEmpty(timeData[0]) ? "5" : timeData[0];
if (!string.IsNullOrEmpty(timeData[1]) && timeData[1].Contains(":"))
{
string[] onTime = timeData[1].Split(':');
txtBoxOnYY.Text = onTime[0];
txtBoxOnMM.Text = onTime[1];
txtBoxOnSS.Text = onTime[2];
}
if (!string.IsNullOrEmpty(timeData[2]) && timeData[2].Contains(":"))
{
string[] offTime = timeData[2].Split(':');
txtBoxOffYY.Text = offTime[0];
txtBoxOffMM.Text = offTime[1];
txtBoxOffSS.Text = offTime[2];
}
txtBoxOnYY.TextChanged += ValidateInputs; txtBoxOnYY.TextChanged += ValidateInputs;
txtBoxOnMM.TextChanged += ValidateInputs; txtBoxOnMM.TextChanged += ValidateInputs;
txtBoxOnSS.TextChanged += ValidateInputs;
txtBoxOffYY.TextChanged += ValidateInputs; txtBoxOffYY.TextChanged += ValidateInputs;
txtBoxOffMM.TextChanged += ValidateInputs; txtBoxOffMM.TextChanged += ValidateInputs;
txtBoxOffSS.TextChanged += ValidateInputs;
txtBoxOnYY.PlaceholderText = "YY"; txtBoxOnYY.PlaceholderText = "YY";
txtBoxOnMM.PlaceholderText = "MM"; txtBoxOnMM.PlaceholderText = "MM";
txtBoxOnSS.PlaceholderText = "SS";
txtBoxOffYY.PlaceholderText = "YY"; txtBoxOffYY.PlaceholderText = "YY";
txtBoxOffMM.PlaceholderText = "MM"; txtBoxOffMM.PlaceholderText = "MM";
txtBoxOffSS.PlaceholderText = "SS";
LoadAndParseFile();
}
// ⭐️ 오른쪽 그리드뷰 디자인 시안을 반영한 메서드
// ⭐️ 오른쪽 그리드뷰 디자인 시안을 반영한 메서드
private void InitDataGridViewStyles()
{
grdDataList.AllowUserToResizeRows = false;
grdDataList.AllowUserToResizeColumns = false;
grdDataList.RowHeadersVisible = false; // 왼쪽 화살표 열 숨김
grdDataList.AllowUserToAddRows = false; // 빈 칸 추가 방지
grdDataList.ReadOnly = true; // 읽기 전용
grdDataList.SelectionMode = DataGridViewSelectionMode.FullRowSelect; // 행 선택
grdDataList.MultiSelect = false;
// 커스텀 헤더 스타일을 적용하기 위해 반드시 false 설정
grdDataList.EnableHeadersVisualStyles = false;
// 그리드 전체 배경 및 기본 테두리 제거 (시안처럼 하얗고 투명하게)
grdDataList.BackgroundColor = Color.White;
grdDataList.BorderStyle = BorderStyle.None;
// 셀 구분선 설정 (옅은 회색 가로선만 남김)
grdDataList.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
grdDataList.GridColor = Color.FromArgb(240, 242, 245);
// [상단 헤더 스타일 수정]
DataGridViewCellStyle headerStyle = new DataGridViewCellStyle();
headerStyle.BackColor = Color.FromArgb(44, 62, 80);
headerStyle.ForeColor = Color.White;
headerStyle.Font = new Font("맑은 고딕", 9.5F, FontStyle.Bold);
headerStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// 행을 선택하더라도 헤더의 선택 배경색/글자색이 기본 배경색과 똑같이 유지되도록 고정
headerStyle.SelectionBackColor = Color.FromArgb(44, 62, 80);
headerStyle.SelectionForeColor = Color.White;
grdDataList.ColumnHeadersDefaultCellStyle = headerStyle;
grdDataList.ColumnHeadersHeight = 38; // 헤더 높이 여유롭게 조정
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
// 행 선택 시 헤더 스타일 상속으로 인한 테두리 및 색상 왜곡 방지
grdDataList.EnableHeadersVisualStyles = false;
// [일반 데이터 셀 스타일 수정]
DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
cellStyle.BackColor = Color.White;
cellStyle.ForeColor = Color.FromArgb(50, 50, 50); // 부드러운 차콜 블랙
cellStyle.Font = new Font("맑은 고딕", 9F, FontStyle.Regular);
cellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// 행 선택(클릭) 시 파란색 대신 부드러운 회청색으로 채우기
cellStyle.SelectionBackColor = Color.FromArgb(242, 246, 252);
cellStyle.SelectionForeColor = Color.FromArgb(50, 50, 50);
grdDataList.DefaultCellStyle = cellStyle;
// 시안처럼 행 간격(높이)을 시원하게 벌려 가시성을 높임
grdDataList.RowTemplate.Height = 38;
grdDataList.ClearSelection();
}
private void ConfigureModernStyles()
{
// 수정 버튼 스타일 설정 (테두리 삭제)
btnUpdate.FlatStyle = FlatStyle.Flat;
btnUpdate.FlatAppearance.BorderSize = 0;
// 취소 버튼 스타일 설정 (테두리 삭제 및 부드러운 회색)
btnCancel.FlatStyle = FlatStyle.Flat;
btnCancel.FlatAppearance.BorderSize = 0;
btnCancel.BackColor = Color.FromArgb(230, 235, 240);
btnCancel.ForeColor = Color.FromArgb(80, 80, 80);
// 둥근 처리를 위한 Paint 이벤트 연결
if (lblBox != null) lblBox.Paint += lblBox_Paint;
btnUpdate.Paint += Button_Paint;
btnCancel.Paint += Button_Paint;
}
// 둥근 모서리 경로를 만들어주는 공통 메서드
private GraphicsPath GetRoundPath(Rectangle bounds, int radius)
{
GraphicsPath path = new GraphicsPath();
int diameter = radius * 2;
path.AddArc(bounds.X, bounds.Y, diameter, diameter, 180, 90);
path.AddArc(bounds.Right - diameter, bounds.Y, diameter, diameter, 270, 90);
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
path.AddArc(bounds.X, bounds.Bottom - diameter, diameter, diameter, 90, 90);
path.CloseAllFigures();
return path;
}
// 흰색 배경 박스 둥글게 자르기
private void lblBox_Paint(object? sender, PaintEventArgs e)
{
if (sender is Control control)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, control.Width, control.Height), CornerRadiusValue))
{
control.Region = new Region(path);
}
}
}
// 버튼들 둥글게 자르기
private void Button_Paint(object? sender, PaintEventArgs e)
{
if (sender is Button button)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, button.Width, button.Height), 10))
{
button.Region = new Region(path);
}
}
} }
private void ValidateInputs(object? sender, EventArgs e) private void ValidateInputs(object? sender, EventArgs e)
{ {
// 프로그램 시간 조건 체크
bool isOnYYEmpty = string.IsNullOrWhiteSpace(txtBoxOnYY.Text); bool isOnYYEmpty = string.IsNullOrWhiteSpace(txtBoxOnYY.Text);
bool isOnMMEmpty = string.IsNullOrWhiteSpace(txtBoxOnMM.Text); bool isOnMMEmpty = string.IsNullOrWhiteSpace(txtBoxOnMM.Text);
bool isOnSSEmpty = string.IsNullOrWhiteSpace(txtBoxOnSS.Text);
bool isOffYYEmpty = string.IsNullOrWhiteSpace(txtBoxOffYY.Text); bool isOffYYEmpty = string.IsNullOrWhiteSpace(txtBoxOffYY.Text);
bool isOffMMEmpty = string.IsNullOrWhiteSpace(@txtBoxOffMM.Text); bool isOffMMEmpty = string.IsNullOrWhiteSpace(txtBoxOffMM.Text);
bool isOffSSEmpty = string.IsNullOrWhiteSpace(txtBoxOffSS.Text);
// 둘 다 비어있거나(AND), 둘 다 비어있지 않거나(AND) bool isTimeValid = (isOnYYEmpty && isOnMMEmpty && isOnSSEmpty && isOffYYEmpty && isOffMMEmpty && isOffSSEmpty) ||
bool isTimeValid = (isOnYYEmpty && isOnMMEmpty && isOffYYEmpty && isOffMMEmpty) || (!isOnYYEmpty && !isOnMMEmpty && !isOffYYEmpty && !isOffMMEmpty); (!isOnYYEmpty && !isOnMMEmpty && !isOnSSEmpty && !isOffYYEmpty && !isOffMMEmpty && !isOffSSEmpty);
// 저장 버튼 활성화
btnUpdate.Enabled = isTimeValid; btnUpdate.Enabled = isTimeValid;
if (isTimeValid)
{
btnUpdate.BackColor = Color.FromArgb(52, 152, 219); // 활성화 스카이블루
btnUpdate.ForeColor = Color.White;
}
else
{
btnUpdate.BackColor = Color.FromArgb(180, 210, 235); // 비활성화 흐린 블루
btnUpdate.ForeColor = Color.White;
}
} }
private void btnCancel_MouseClick(object sender, MouseEventArgs e) private void btnCancel_MouseClick(object sender, MouseEventArgs e)
@@ -50,8 +226,53 @@ namespace ControlServer
private void btnUpdate_MouseClick(object sender, MouseEventArgs e) private void btnUpdate_MouseClick(object sender, MouseEventArgs e)
{ {
// 수정 string displayTime = txtBoxDisplay.Text;
// 수정 시 DB 저장 string onTime = txtBoxOnYY.Text + ":" + txtBoxOnMM.Text + ":" + txtBoxOnSS.Text;
string offTime = txtBoxOffYY.Text + ":" + txtBoxOffMM.Text + ":" + txtBoxOffSS.Text;
_mainForm.SaveProgramTimesToGrid(_targetIP, displayTime, onTime, offTime);
string protocol = $"SET_TIME|{displayTime}\n";
_mainForm.SendDataToSingleAgent(_targetIP, protocol);
MessageBox.Show("수정되었습니다.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
private void LoadAndParseFile()
{
if (!File.Exists(_filePath)) return;
string fileContent = File.ReadAllText(_filePath);
if (string.IsNullOrWhiteSpace(fileContent)) return;
ParseAndBindServerData(fileContent);
}
private void ParseAndBindServerData(string rawData)
{
try
{
var doc = System.Xml.Linq.XDocument.Parse(rawData);
grdDataList.Rows.Clear();
foreach (var item in doc.Descendants("AuctionTable"))
{
grdDataList.Rows.Add(
item.Element("aucDate")?.Value,
item.Element("itemName")?.Value,
item.Element("origin")?.Value,
item.Element("totalQty")?.Value,
item.Element("fixPriceQty")?.Value,
item.Element("totalAmt")?.Value,
item.Element("fixPriceAmt")?.Value
);
}
}
catch (Exception ex)
{
MessageBox.Show("XML 파싱 에러: " + ex.Message, "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} }
} }
} }

View File

@@ -117,4 +117,25 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="Col0.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Col6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

View File

@@ -1,166 +0,0 @@
namespace ControlServer
{
partial class Form4
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
DataGridViewCellStyle dataGridViewCellStyle7 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle12 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle8 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle9 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle10 = new DataGridViewCellStyle();
DataGridViewCellStyle dataGridViewCellStyle11 = new DataGridViewCellStyle();
grdLog = new DataGridView();
Col5 = new DataGridViewTextBoxColumn();
Col0 = new DataGridViewTextBoxColumn();
Col3 = new DataGridViewTextBoxColumn();
Col4 = new DataGridViewTextBoxColumn();
Col6 = new DataGridViewTextBoxColumn();
Col7 = new DataGridViewTextBoxColumn();
btnPrev = new Button();
((System.ComponentModel.ISupportInitialize)grdLog).BeginInit();
SuspendLayout();
//
// grdLog
//
dataGridViewCellStyle7.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle7.BackColor = SystemColors.ButtonShadow;
dataGridViewCellStyle7.Font = new Font("맑은 고딕", 9F);
dataGridViewCellStyle7.ForeColor = SystemColors.WindowText;
dataGridViewCellStyle7.SelectionBackColor = SystemColors.Highlight;
dataGridViewCellStyle7.SelectionForeColor = SystemColors.HighlightText;
dataGridViewCellStyle7.WrapMode = DataGridViewTriState.True;
grdLog.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7;
grdLog.ColumnHeadersHeight = 29;
grdLog.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
grdLog.Columns.AddRange(new DataGridViewColumn[] { Col5, Col0, Col3, Col4, Col6, Col7 });
dataGridViewCellStyle12.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle12.BackColor = SystemColors.Window;
dataGridViewCellStyle12.Font = new Font("맑은 고딕", 9F);
dataGridViewCellStyle12.ForeColor = SystemColors.ControlText;
dataGridViewCellStyle12.SelectionBackColor = SystemColors.Highlight;
dataGridViewCellStyle12.SelectionForeColor = SystemColors.HighlightText;
dataGridViewCellStyle12.WrapMode = DataGridViewTriState.False;
grdLog.DefaultCellStyle = dataGridViewCellStyle12;
grdLog.Location = new Point(164, 87);
grdLog.Name = "grdLog";
grdLog.RowHeadersWidth = 51;
grdLog.Size = new Size(1000, 638);
grdLog.TabIndex = 4;
//
// Col5
//
dataGridViewCellStyle8.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col5.DefaultCellStyle = dataGridViewCellStyle8;
Col5.Frozen = true;
Col5.HeaderText = "일시";
Col5.MinimumWidth = 6;
Col5.Name = "Col5";
Col5.Width = 220;
//
// Col0
//
dataGridViewCellStyle9.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col0.DefaultCellStyle = dataGridViewCellStyle9;
Col0.Frozen = true;
Col0.HeaderText = "단말기명";
Col0.MinimumWidth = 6;
Col0.Name = "Col0";
Col0.Width = 170;
//
// Col3
//
dataGridViewCellStyle10.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col3.DefaultCellStyle = dataGridViewCellStyle10;
Col3.Frozen = true;
Col3.HeaderText = "명령 유형";
Col3.MinimumWidth = 6;
Col3.Name = "Col3";
Col3.Width = 125;
//
// Col4
//
dataGridViewCellStyle11.Alignment = DataGridViewContentAlignment.MiddleCenter;
Col4.DefaultCellStyle = dataGridViewCellStyle11;
Col4.Frozen = true;
Col4.HeaderText = "수행자";
Col4.MinimumWidth = 6;
Col4.Name = "Col4";
Col4.Width = 125;
//
// Col6
//
Col6.Frozen = true;
Col6.HeaderText = "결과";
Col6.MinimumWidth = 6;
Col6.Name = "Col6";
Col6.Width = 125;
//
// Col7
//
Col7.Frozen = true;
Col7.HeaderText = "상세내용";
Col7.MinimumWidth = 6;
Col7.Name = "Col7";
Col7.Width = 285;
//
// btnPrev
//
btnPrev.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129);
btnPrev.Location = new Point(164, 12);
btnPrev.Name = "btnPrev";
btnPrev.Size = new Size(174, 56);
btnPrev.TabIndex = 13;
btnPrev.Text = "이전";
btnPrev.UseVisualStyleBackColor = true;
btnPrev.MouseClick += btnPrev_MouseClick;
//
// Form4
//
AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1357, 737);
Controls.Add(btnPrev);
Controls.Add(grdLog);
Name = "Form4";
Text = "Form4";
((System.ComponentModel.ISupportInitialize)grdLog).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView grdLog;
private DataGridViewTextBoxColumn Col5;
private DataGridViewTextBoxColumn Col0;
private DataGridViewTextBoxColumn Col3;
private DataGridViewTextBoxColumn Col4;
private DataGridViewTextBoxColumn Col6;
private DataGridViewTextBoxColumn Col7;
private Button btnPrev;
}
}

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ControlServer
{
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
grdLog.RowHeadersVisible = false; // 그리드 자동으로 생성되는 첫 번째 열 제거
grdLog.AllowUserToAddRows = false; // 새 행 입력용 기본 로우 제거
grdLog.EnableHeadersVisualStyles = false; // 헤더 기본 테마 사용 안 함
grdLog.ColumnHeadersDefaultCellStyle.BackColor = Color.LightGray; // 헤더 배경색
grdLog.ColumnHeadersHeight = 40; // 헤더 높이
grdLog.RowHeadersVisible = false; // 행 헤더 제거
grdLog.AllowUserToAddRows = false; // // 행 추가 금지
grdLog.AllowUserToResizeRows = false; // 행 높이 조절 금지
grdLog.AllowUserToResizeColumns = false; // 열 너비 조절 금지
grdLog.ReadOnly = true; // 읽기 전용
grdLog.ClearSelection();
}
private void btnPrev_MouseClick(object sender, MouseEventArgs e)
{
this.Close();
}
}
}

View File

@@ -69,5 +69,45 @@ namespace ControlServer.Properties {
return ((System.Drawing.Bitmap)(obj)); return ((System.Drawing.Bitmap)(obj));
} }
} }
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap imgCountBox {
get {
object obj = ResourceManager.GetObject("imgCountBox", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap imgCountBox1 {
get {
object obj = ResourceManager.GetObject("imgCountBox1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap imgDataRegister {
get {
object obj = ResourceManager.GetObject("imgDataRegister", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다.
/// </summary>
internal static System.Drawing.Bitmap imgDataUpdate {
get {
object obj = ResourceManager.GetObject("imgDataUpdate", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
} }
} }

View File

@@ -118,7 +118,19 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="imgDataRegister" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\imgDataRegister.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="button-search" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="button-search" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\button-search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\button-search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="imgDataUpdate" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\imgDataUpdate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="imgCountBox" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\imgCountBox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="imgCountBox1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\imgCountBox1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

View File

@@ -0,0 +1,49 @@
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
namespace ControlServer
{
public class RoundedPanel : Panel
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int CornerRadius { get; set; } = 30;
public RoundedPanel()
{
this.DoubleBuffered = true;
// 컨트롤의 배경색이 바뀔 때 다시 그리도록 설정
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
// 배경을 투명하게 처리하고 둥근 영역만 남김
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90);
path.AddArc(Width - CornerRadius - 1, 0, CornerRadius, CornerRadius, 270, 90);
path.AddArc(Width - CornerRadius - 1, Height - CornerRadius - 1, CornerRadius, CornerRadius, 0, 90);
path.AddArc(0, Height - CornerRadius - 1, CornerRadius, CornerRadius, 90, 90);
path.CloseAllFigures();
// 영역(Region)을 설정하여 모서리 바깥쪽을 클릭 방지 및 투명 처리
this.Region = new Region(path);
// 배경 채우기
using (SolidBrush brush = new SolidBrush(this.BackColor))
{
e.Graphics.FillPath(brush, path);
}
}
base.OnPaint(e);
}
}
}