티스토리 뷰
[1]Splash(DB에 RGB값을 저장하거나 불러와 그리드에 색을 칠하는 프로그램)
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace _034_Splash
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
List<Border> borderList;
DispatcherTimer t = new DispatcherTimer();
Random r = new Random();
SqlConnection conn;
string connStr = @"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\choi\Desktop\VP02-master (2)\VP02-master\034_Splash\Colors.mdf;Integrated Security = True";
public MainWindow()
{
InitializeComponent();
borderList = new List<Border>
{
bd1, bd2, bd3, bd4, bd5,
bd6, bd7, bd8, bd9, bd10,
bd11, bd12, bd13, bd14, bd15,
bd16, bd17, bd18, bd19, bd20
};
t.Interval = new TimeSpan(0, 0, 1); // 1초
t.Tick += T_Tick;
}
int index = 0;
private void T_Tick(object sender, EventArgs e)
{
string date = DateTime.Now.ToString("yyyy-MM-dd");
string time = DateTime.Now.ToString("HH:mm:ss");
lblDate.Text = date;
lblTime.Text = time;
byte[] colors = new byte[20];
for(int i = 0; i < 20; i++)
{
colors[i] = (byte)(r.Next(256));
borderList[i].Background
= new SolidColorBrush(
Color.FromRgb((byte)0, (byte)0, colors[i]));
}
string sql = string.Format(
"INSERT INTO ColorTable VALUES ('{0}', '{1}'",
date, time);
for(int i = 0; i < 20; i++)
{
sql += string.Format(", {0}", colors[i]);
}
sql += ")";
//MessageBox.Show(sql);
using(conn = new SqlConnection(connStr))
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
string s = "";
s += date + " " + time + " ";
for (int i = 0; i < 20; i++)
s += colors[i] + " ";
lstDB.Items.Add(s);
// 리스트 박스의 스크롤
lstDB.SelectedIndex = index++;
lstDB.ScrollIntoView(lstDB.SelectedItem);
}
bool flag = false;
private void btnRandom_Click(object sender, RoutedEventArgs e)
{
if (flag == false)
{
t.Start();
btnRandom.Content = "정지";
flag = true;
}
else
{
t.Stop();
btnRandom.Content = "랜덤 색깔 표시";
flag= false;
}
}
int id = 0;
// DB에 저장된 색깔 표시
private void btnDB_Click(object sender, RoutedEventArgs e)
{
lstDB.Items.Clear();
string sql = "SELECT * FROM ColorTable";
int[] colors = new int[20];
using (conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
lblDate.Text = reader["Date"].ToString();
lblTime.Text = reader["Time"].ToString();
for(int i=0; i<20; i++)
{
colors[i] = int.Parse(reader[i+3].ToString());
}
string s = "";
s += reader["Date"].ToString() + " "
+ reader["Time"].ToString();
for(int i=0; i<20; i++)
{
s += " " + reader[i + 3].ToString();
}
lstDB.Items.Add(s);
// 스크롤 기능
lstDB.SelectedIndex = id++;
lstDB.ScrollIntoView(lstDB.SelectedItem);
for(int i=0; i<20; i++)
{
borderList[i].Background =
new SolidColorBrush(
Color.FromRgb((byte)0, (byte)0, (byte)colors[i]));
// WPF에서 delay 주기
Dispatcher.Invoke((ThreadStart)(() => { }),
DispatcherPriority.ApplicationIdle);
Thread.Sleep(20); // 0.02 초 delay
}
}
}
}
// DB의 내용을 다 지운다
private void btnReset_Click(object sender, RoutedEventArgs e)
{
lstDB.Items.Clear();
string sql = "DELETE FROM ColorTable";
using(conn= new SqlConnection(connStr))
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
}
private void btnExit_Click(object sender, RoutedEventArgs e)
{
Close();
}
}
}
전체 코드이다.
using System.Data.SqlClient;
using System.Windows.Threading;
Service-Based-Database 사용을 위해 위의 using 두 개를 선언해준다.
저번시간엔 위와같은 레이아웃을 만들어주었다.
List<Border> borderList;
DispatcherTimer t = new DispatcherTimer();
Random r = new Random();
SqlConnection conn;
string connStr = @"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\choi\Desktop\VP02-master (2)\VP02-master\034_Splash\Colors.mdf;Integrated Security = True";
{1}_partial class 안에 Border class타입의 변수들을 저장할 borderList를 선언해준다.
{2}_윈도우폼앱에서 Timer가 WPF에서 DispatcherTimer로 쓰인다.
DispatcherTimer클래스타입의 t를 선언해준다.
{3}_Random class r Declare
{4}_현재 VS installer를 통해 설치한 DB를 사용중이므로 Provider는 따로 입력해주지 않고
LocalDB형식의 MSSQLLocalDB의 문법으로 DB의 주소를 문자열로 저장하여
public MainWindow()
{
InitializeComponent();
borderList = new List<Border>
{
bd1, bd2, bd3, bd4, bd5,
bd6, bd7, bd8, bd9, bd10,
bd11, bd12, bd13, bd14, bd15,
bd16, bd17, bd18, bd19, bd20
};
t.Interval = new TimeSpan(0, 0, 1); // 1초
t.Tick += T_Tick;
}
int index = 0;
선언해준 borderList에 grid의 name을 전부 넣어준 뒤 timespan 으로 t의 인터벌을 1초로 설정해준다.
t.Tick의 eventListener를 T_Tick으로 설정해준뒤 메서드를 생성해준다.
index를 전역변수 0으로 설정해준다.
private void T_Tick(object sender, EventArgs e)
{
string date = DateTime.Now.ToString("yyyy-MM-dd");
string time = DateTime.Now.ToString("HH:mm:ss");
lblDate.Text = date;
lblTime.Text = time;
byte[] colors = new byte[20];
for(int i = 0; i < 20; i++)
{
colors[i] = (byte)(r.Next(256));
borderList[i].Background
= new SolidColorBrush(
Color.FromRgb((byte)0, (byte)0, colors[i]));
}
string sql = string.Format(
"INSERT INTO ColorTable VALUES ('{0}', '{1}'",
date, time);
for(int i = 0; i < 20; i++)
{
sql += string.Format(", {0}", colors[i]);
}
sql += ")";
//MessageBox.Show(sql);
using(conn = new SqlConnection(connStr))
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
string s = "";
s += date + " " + time + " ";
for (int i = 0; i < 20; i++)
s += colors[i] + " ";
lstDB.Items.Add(s);
// 리스트 박스의 스크롤
lstDB.SelectedIndex = index++;
lstDB.ScrollIntoView(lstDB.SelectedItem);
}
T_Tick함수의 코드이다.
{1}_date와 time을 sql형식에 맞춰 string타입으로 작성해준 뒤 xaml에서 설정해준 textblock의 text로 설정준다.
{2}_byte타입으로 20칸짜리 colors배열을 선언해준다.
{3}_for문에서 colors[i]에 0~255사이의 정수값을 저장해준다.(byte배열의 범위와 일치함)
{4}_borderList에 저장된 grid들의 배경색을 SolidColorBrush함수를 사용하여 color[i]의 값을 참조하여 칠해준다.
string sql = string.Format(
"INSERT INTO ColorTable VALUES ('{0}', '{1}'",
date, time);
for(int i = 0; i < 20; i++)
{
sql += string.Format(", {0}", colors[i]);
}
sql += ")";
{1}_string 타입의 sql을 SQL문법에 맞추어 작성해준다 (date와 time을 인자로 받도록) - 값을 테이블에 추가해주는 메서드임
{2}_for문을 20번 돌려 string.Format에 {0} = colors[i]를 지정해준다 마지막에 )를 삽입해 sql문을 완성한다.
의문점 : {0}을 더해주면 {0},{1},{0},{0},{0}. . .이 되는건지
using(conn = new SqlConnection(connStr))
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
using을 사용하여 이 함수 안에서 잠시 사용해준다
(C++의 인라인함수나 lamda식처럼 함수가 끝날 때 heap에서 메모리를 지워주는 것인지)
conn을 설정한 후 conn을 기반으로 comm을 작성하여 executenonquery를 실행해준다.
ExecuteNonQuery함수는 변경된 테이블의 cell속성등을 초기화해주는 query함수임
string s = "";
s += date + " " + time + " ";
for (int i = 0; i < 20; i++)
s += colors[i] + " ";
lstDB.Items.Add(s);
string타입 s를 만들어 방금 난수를 선언했던 colors의 값들을 뽑아와 저장해준 후 lstDB의 아이템으로 추가해준다.
lstDB.SelectedIndex = index++;
lstDB.ScrollIntoView(lstDB.SelectedItem);
bool flag = false;
{1}_lstDB의 선택값을 index++값으로 설정하여 T_Tick에 의해 계속 값이 추가될 때 가장 마지막에 추가된 값으로 selectedItem을 설정{2}_ScrollIntoView를 마지막 값으로 설정하여 계속 scroll이 마지막값을 트래킹함
{3}_flag를 false로 하여 선언해줌
private void btnRandom_Click(object sender, RoutedEventArgs e)
{
if (flag == false)
{
t.Start();
btnRandom.Content = "정지";
flag = true;
}
else
{
t.Stop();
btnRandom.Content = "랜덤 색깔 표시";
flag= false;
}
}
int id = 0;
{1}_만약 랜덤으로 출력 버튼을 눌렀을 때 멈춰있는 상태였다면 버튼의 content를 '정지'로 바꾸고 flag를 true로 해준 뒤 Tick을 실행
{2}_그렇지 않다면 Tick을 멈추고 content를 원래대로 바꾼 뒤 flag를 false로 해줌
{3}_id를 int형 0으로 선언해줌
private void btnDB_Click(object sender, RoutedEventArgs e)
{
lstDB.Items.Clear();
string sql = "SELECT * FROM ColorTable";
int[] colors = new int[20];
using (conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
lblDate.Text = reader["Date"].ToString();
lblTime.Text = reader["Time"].ToString();
for(int i=0; i<20; i++)
{
colors[i] = int.Parse(reader[i+3].ToString());
}
string s = "";
s += reader["Date"].ToString() + " "
+ reader["Time"].ToString();
for(int i=0; i<20; i++)
{
s += " " + reader[i + 3].ToString();
}
lstDB.Items.Add(s);
// 스크롤 기능
lstDB.SelectedIndex = id++;
lstDB.ScrollIntoView(lstDB.SelectedItem);
for(int i=0; i<20; i++)
{
borderList[i].Background =
new SolidColorBrush(
Color.FromRgb((byte)0, (byte)0, (byte)colors[i]));
// WPF에서 delay 주기
Dispatcher.Invoke((ThreadStart)(() => { }),
DispatcherPriority.ApplicationIdle);
Thread.Sleep(20); // 0.02 초 delay
}
}
}
}
DB에 저장된 색깔 표시 버튼을 눌렀을 때의 메서드이다.
{1}_현재lstDB에 적혀있는 item들을 clear해준 뒤
{2}_sql에 table값 전체를 불러오는 명령어를 string형태로 저장해준다.
{3}_int형 배열 colors를 만들어 랜덤버튼에서 쓰던 것 처럼 using문을 작성해준 뒤 중괄호를 열어준다.
{4}_connection을 열어준 뒤 reader를 선언해준다.
{5}_Read Value가 true일때 while문이 돌아가도록 선언해준다.
{6}_xaml에서 선언해준 date와 time의 텍스트를 받아오는데 SqlDataReader를 사용하면 대괄호 안의 값을 string으로 받아
get한다.
{7}_LocalDB table의 1,2,3번째 값은 Id,Date,Time이므로 4번째값부터(i+3) p값을 차례대로 받아와 colors에 넣어준다.
{8}_string type s를 생성해준 뒤 reader로 Date와 Time값을 받아 더해주고
{9}_reader로 읽어온 테이블의 4~end값 까지의 값을 모두 더해준 뒤(colors[i]의 값를 받아도 된다.) lstDB에 저장해준다.
{10}_id값을 더미로 한 ScrollView를 설정해준다.
{11}_그 다음 borderList에 저장된 border들의 background를 FromRgb함수를 사용하여 칠해주는데
// WPF에서 delay 주기
Dispatcher.Invoke((ThreadStart)(() => { }),
DispatcherPriority.ApplicationIdle);
Thread.Sleep(20); // 0.02 초 delay
WPF프로젝트의 delay구현부이다.
이를 사용하기 위해 using System.Window.Threading; 을 추가해주어야한다.
자세히는 모르겠지만 멀티스레딩을 해주는 것 같다.
{1}_멀티스레드를 설정함
{2}_Dispatch의 우선순위를 정해주는 것 같음
현재 ApplicationIdle의 value는 2임 2순위인 것 같고 메인스레드가 휴면상태일 때 진행되는 것 같음
{3}_Sleep으로 메인스레드를 0.02초동안 휴면상태로 보냄
요약 : Sleep으로 0.02초동안 메인스레드를 재움으로써 ApplicationIdle의 우선순위에 따라 Idle일때 발동하는
thread delegate를 반환함 여기서 subthread를 시작하는데 내용이 빈칸이므로 delegate는 null을 반환하게되고
0.02초동안 아무일도 일어나지 않고 null만 반환하다가 메인스레드가 다시 깨어남.
//주관적인 생각입니다...
private void btnReset_Click(object sender, RoutedEventArgs e)
{
lstDB.Items.Clear();
string sql = "DELETE FROM ColorTable";
using(conn= new SqlConnection(connStr))
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
}
다음은 리셋버튼이다. lstDB의 아이템들을 clear한 상태로 시작한다.
{1}_sql명령어를 delete로 설정해준다.
{2}_위의 버튼들과 마찬가지로 using을 사용하여 conn과 cmd를 설정해준 뒤 중괄호를 열어준다.
{3}_conn을 열고 cmd로 변경사항을 query전송한다.(sql의 내용이 DELETE이고 conn이 sql을 받아 cmd에 넘겼으므로 모두 삭제됨)
private void btnExit_Click(object sender, RoutedEventArgs e)
{
Close();
}
마지막 종료버튼은 close함수를 사용하여 window를 닫아주면 된다.
감사합니다
'VS-02분반수업' 카테고리의 다른 글
VP(22-05-25) (0) | 2022.05.25 |
---|---|
VP(22-05-20) (0) | 2022.05.24 |
VP02(22-05-11) (0) | 2022.05.16 |
VP(22-05-06) (0) | 2022.05.08 |
VP(22-05-04) (0) | 2022.05.08 |