솔루션 탐색기에서
divForm 프로젝트를 복사해서 그대로 붙여넣기해주자
이제 새로 만든 MemberForm을 편집해보자
MemberForm에서 저장 메서드(UPDATE문) 구현
// 저장 버튼 클릭 이벤트
private void BtnSave_Click(object sender, EventArgs e)
{
if(String.IsNullOrEmpty(TxtAddr.Text) || string.IsNullOrEmpty(TxtNames.Text)
|| string.IsNullOrEmpty(TxtMobile.Text) || string.IsNullOrEmpty(TxtEmail.Text))
{
MetroMessageBox.Show(this, "빈 값은 저장할 수 없습니다", "경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
SaveProcess();
UpdateData(); // 그리드를 다시 불러서 리프레쉬된다
ClearTextControls();
}
// 저장 버튼의 메서드
private void SaveProcess()
{
if (String.IsNullOrEmpty(mode)) // 아무것도 입력안했을때 오류메세지
{
MetroMessageBox.Show(this, "신규버튼을 누르고 데이터를 저장하십시오", "경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//DB저장 프로세스
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
string strQuery = "";
if (mode == "UPDATE")
{
strQuery = "UPDATE dbo.membertbl " +
" SET Names = @Names " +
" , Levels = @Levels " +
" , Addr = @Addr " +
" , Mobile = @Mobile " +
" , Email = @Email " +
" WHERE Idx = @Idx";
}
else if (mode == "INSERT")
{
strQuery = "INSERT INTO dbo.membertbl(Names, Levels, Addr, Mobile, Email) " +
"VALUES(@Names, @Levels, @Addr, @Mobile, @Email) ";
}
cmd.CommandText = strQuery;
SqlParameter parmNames = new SqlParameter("@Names", SqlDbType.NVarChar, 45);
parmNames.Value = TxtNames.Text;
cmd.Parameters.Add(parmNames);
SqlParameter parmLevels = new SqlParameter("@Levels", SqlDbType.Char, 1);
parmLevels.Value = CboLevels.SelectedItem;
cmd.Parameters.Add(parmLevels);
SqlParameter parmAddr = new SqlParameter("@Addr", SqlDbType.VarChar, 100);
parmAddr.Value = TxtAddr.Text;
cmd.Parameters.Add(parmAddr);
SqlParameter parmMobile = new SqlParameter("@Mobile", SqlDbType.VarChar, 13);
parmMobile.Value = TxtMobile.Text;
cmd.Parameters.Add(parmMobile);
SqlParameter parmEmail = new SqlParameter("@Email", SqlDbType.VarChar, 50);
parmEmail.Value = TxtEmail.Text;
cmd.Parameters.Add(parmEmail);
if(mode == "UPDATE")
{
SqlParameter parmIdx = new SqlParameter("@Idx", SqlDbType.Int);
parmIdx.Value = TxtIdx.Text;
cmd.Parameters.Add(parmIdx);
}
cmd.ExecuteNonQuery(); // 쿼리값을 돌려받지 않으니까 ExecuteNonQuery을 써준다
}
}
// DB 데이터 업데이트
private void UpdateData()
{
private void UpdateData()
{
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open(); // DB 열기
string strQuery = "SELECT Idx ,Names ,Levels ,Addr ,Mobile ,Email " +
"FROM dbo.membertbl ";
SqlCommand cmd = new SqlCommand(strQuery, conn);
SqlDataAdapter dataAdapter = new SqlDataAdapter(strQuery, conn);
DataSet ds = new DataSet();
dataAdapter.Fill(ds, "membertbl");
GrdMemberTbl.DataSource = ds;
GrdMemberTbl.DataMember = "membertbl";
}
}
// 버튼을 클릭했을때 빈칸으로 만들어주는 메서드
private void ClearTextControls() // 중복된 코드를 메서드로 묶어주기
{
TxtIdx.Text = TxtNames.Text = TxtAddr.Text = TxtEmail.Text = TxtMobile.Text = "";
CboLevels.SelectedIndex = -1; // 콤보박스의 값 초기화(빈칸)
TxtIdx.ReadOnly = true;
TxtIdx.BackColor = Color.Beige;
TxtIdx.Focus();
}
신규 저장 메서드(INSERT문) 구현(구문은 UPDATE문의 else if 코드를 참고)
지금까지 코드 창만 4가지가되는데 그 중 중복되는 코드들을 줄여보자
Commons 항목에 밑의 코드를 적어놓자
namespace BookRentalShop20
{
public static class Commons
{
//공용 연결문자열
public static string COONSTRING =
" Data Source = 192.168.0.124; " +
" Initial Catalog = BookRentalShopDB; " +
" Persist Security Info=True;" +
" User ID = sa; Password=p@ssw0rd!";
}
}
DivForm의 SSMS 로그인하는 코드를 지워주자
로그인 하는 코드를 지웠으니 그게 관련된 코드에 에러가 뜰 것이다.
이 코드의 이름을 Commons.COONSTRING으로 바꿔주자
이 코드 수정을 DivForm, MemberForm, LoginForm에도 전부 수정해준다.
이게 폼이 4가지밖에 안되서 금방끝나지만 30개 이상이 됬을때는 이렇게 일일이 지정해주지 않아도 될 것이다.
책 관리 형식의 폼을 또 만들어보자
솔루션 탐색기에서 membertbl을 복사해서 그래도 컨트롤+V를 한다음에 디자이너.cs와 memberForm 쿼리창의 memberForm을 BooksTbl로 수정해주자
BooksForm 생성
private void UpdateData()
{
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open(); // DB 열기
string strQuery = "SELECT b.Idx, b.Author, b.Division, " +
" d.Names AS '장르', b.Names, b.ReleaseDate, b.ISBN, " +
" REPLACE(CONVERT(VARCHAR, CONVERT(Money, b.Price), 1), '.00', '') AS Price " +
" FROM dbo.bookstbl AS b " +
" INNER JOIN dbo.divtbl AS d " +
" ON b.Division = d.Division ";
//SqlCommand cmd = new SqlCommand(strQuery, conn);
SqlDataAdapter dataAdapter = new SqlDataAdapter(strQuery, conn);
DataSet ds = new DataSet();
dataAdapter.Fill(ds, "bookstbl");
GrdBooksTbl.DataSource = ds;
GrdBooksTbl.DataMember = "bookstbl";
}
DataGridViewColumn column = GrdBooksTbl.Columns[1];
column.Visible = false;
}
발간일에 DateTimePicker을 추가해주자, 텍스트를 전부 수정하고 TabIndex를 순서대로 지정해주자
테이블의 데이터를 클릭했을때 각 텍스트박스에 알맞는 데이터들이 입력되는 메서드 구문
private void GrdDivTbl_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex > -1) // 첫번째 인덱스가 0이니까 -1로해준다
{
DataGridViewRow data = GrdBooksTbl.Rows[e.RowIndex];
TxtIdx.Text = data.Cells[0].Value.ToString(); // object는 Tostring을 때려주자
TxtAuthor.Text = data.Cells[1].Value.ToString();
TxtIdx.ReadOnly = true;
TxtIdx.BackColor = Color.Beige;
CboDivision.SelectedIndex = CboDivision.FindString(data.Cells[2].Value.ToString());
TxtName.Text = data.Cells[4].Value.ToString();
DtpReleaseDate.Value = DateTime.Parse(data.Cells[5].Value.ToString());
TxtISBN.Text = data.Cells[6].Value.ToString();
TxtPrice.Text = data.Cells[7].Value.ToString();
mode = "UPDATE"; // 수정은 UPDATE
}
}
위의 이미지대로 봤을때, 데이터를 클릭하면 빈칸에 해당 데이터가 출력되지만 장르 콤보박스에는 출력되지 않는다.
이걸 한번 잡아보자.
UPDATE문, INSERT문 구현하기
//DB저장 프로세스
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
string strQuery = "";
if (mode == "UPDATE")
{
strQuery = " UPDATE dbo.bookstbl " +
" SET Author = @Author " +
", Division = @Division " +
", Names = @Names " +
", ReleaseDate = @ReleaseDate " +
", ISBN = @ISBN " +
", Price = @Price " +
" WHERE Idx = @Idx";
}
else if (mode == "INSERT")
{
strQuery = "INSERT INTO dbo.bookstbl(Author, Division, Names, ReleaseDate, ISBN, Price) " +
" VALUES(@Author, @Division, @Names, @ReleaseDate, @ISBN, @Price)";
}
cmd.CommandText = strQuery;
SqlParameter parmAuthor = new SqlParameter("@Author", SqlDbType.VarChar, 45);
parmAuthor.Value = TxtAuthor.Text;
cmd.Parameters.Add(parmAuthor);
SqlParameter parmDivision = new SqlParameter("@Division", SqlDbType.Char, 4);
parmDivision.Value = CboDivision.SelectedValue;
cmd.Parameters.Add(parmDivision);
SqlParameter parmNames = new SqlParameter("@Names", SqlDbType.Char, 100);
parmNames.Value = TxtName.Text;
cmd.Parameters.Add(parmNames);
SqlParameter parmReleaseDate = new SqlParameter("@ReleaseDate", SqlDbType.Date);
parmReleaseDate.Value = DtpReleaseDate.Value;
cmd.Parameters.Add(parmReleaseDate);
SqlParameter parmISBN = new SqlParameter("@ISBN", SqlDbType.VarChar, 200);
parmISBN.Value = TxtISBN.Text;
cmd.Parameters.Add(parmISBN);
SqlParameter parmPrice = new SqlParameter("@Price", SqlDbType.Decimal, 10);
parmPrice.Value = TxtPrice.Text;
cmd.Parameters.Add(parmPrice);
if(mode == "UPDATE")
{
SqlParameter parmIdx = new SqlParameter("@Idx", SqlDbType.Int);
parmIdx.Value = TxtIdx.Text;
cmd.Parameters.Add(parmIdx);
}
cmd.ExecuteNonQuery(); // 쿼리값을 돌려받지 않으니까 ExecuteNonQuery을 써준다
}
Parameter값을 텍스트 박스의 이름과 열의 이름을 맞춰서 구문을 작성해준다(if문에 해당되는 쿼리문을 붙여넣기도 해준다)
BooksForm 전체 코드
using MetroFramework;
using MetroFramework.Forms;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;
namespace BookRentalShop20
{
public partial class BooksForm : MetroForm
{
string mode = "";
public BooksForm()
{
InitializeComponent();
}
private void GrdDivTbl_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex > -1) // 첫번째 인덱스가 0이니까 -1로해준다
{
DataGridViewRow data = GrdBooksTbl.Rows[e.RowIndex];
TxtIdx.Text = data.Cells[0].Value.ToString(); // object는 Tostring을 때려주자
TxtAuthor.Text = data.Cells[1].Value.ToString();
TxtIdx.ReadOnly = true;
TxtIdx.BackColor = Color.Beige;
// Cells[3] : "로맨스", "SF/판타지"
// CboDivision.SelectedIndex = CboDivision.FindString(data.Cells[3].Value.ToString());
// cells[2] : "B001", "B006"
CboDivision.SelectedValue = data.Cells[2].Value;
TxtName.Text = data.Cells[4].Value.ToString();
DtpReleaseDate.Format = DateTimePickerFormat.Custom;
DtpReleaseDate.CustomFormat = "yyyy-MM-dd";
DtpReleaseDate.Value = DateTime.Parse(data.Cells[5].Value.ToString());
TxtISBN.Text = data.Cells[6].Value.ToString();
TxtPrice.Text = data.Cells[7].Value.ToString();
mode = "UPDATE"; // 수정은 UPDATE
}
}
// 신규 버튼 클릭 이벤트
private void BtnNew_Click(object sender, EventArgs e)
{
ClearTextControls();
mode = "INSERT"; // 신규는 INSERT
}
// 저장 버튼 클릭 이벤트
private void BtnSave_Click(object sender, EventArgs e)
{
if(String.IsNullOrEmpty(TxtName.Text) || string.IsNullOrEmpty(TxtAuthor.Text)
|| string.IsNullOrEmpty(TxtISBN.Text) ) // 나머지 컨트롤(총 6개) 검사해야한다
{
MetroMessageBox.Show(this, "빈 값은 저장할 수 없습니다", "경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
SaveProcess();
UpdateData();
ClearTextControls();
}
// 저장 버튼의 메서드
private void SaveProcess()
{
if (String.IsNullOrEmpty(mode)) // 아무것도 입력안했을때 오류메세지
{
MetroMessageBox.Show(this, "신규버튼을 누르고 데이터를 저장하십시오", "경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//DB저장 프로세스
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
string strQuery = "";
if (mode == "UPDATE")
{
strQuery = " UPDATE dbo.bookstbl " +
" SET Author = @Author " +
", Division = @Division " +
", Names = @Names " +
", ReleaseDate = @ReleaseDate " +
", ISBN = @ISBN " +
", Price = @Price " +
" WHERE Idx = @Idx";
}
else if (mode == "INSERT")
{
strQuery = "INSERT INTO dbo.bookstbl(Author, Division, Names, ReleaseDate, ISBN, Price) " +
" VALUES(@Author, @Division, @Names, @ReleaseDate, @ISBN, @Price)";
}
cmd.CommandText = strQuery;
SqlParameter parmAuthor = new SqlParameter("@Author", SqlDbType.VarChar, 45);
parmAuthor.Value = TxtAuthor.Text;
cmd.Parameters.Add(parmAuthor);
SqlParameter parmDivision = new SqlParameter("@Division", SqlDbType.Char, 4);
parmDivision.Value = CboDivision.SelectedValue;
cmd.Parameters.Add(parmDivision);
SqlParameter parmNames = new SqlParameter("@Names", SqlDbType.Char, 100);
parmNames.Value = TxtName.Text;
cmd.Parameters.Add(parmNames);
SqlParameter parmReleaseDate = new SqlParameter("@ReleaseDate", SqlDbType.Date);
parmReleaseDate.Value = DtpReleaseDate.Value;
cmd.Parameters.Add(parmReleaseDate);
SqlParameter parmISBN = new SqlParameter("@ISBN", SqlDbType.VarChar, 200);
parmISBN.Value = TxtISBN.Text;
cmd.Parameters.Add(parmISBN);
SqlParameter parmPrice = new SqlParameter("@Price", SqlDbType.Decimal, 10);
parmPrice.Value = TxtPrice.Text;
cmd.Parameters.Add(parmPrice);
if(mode == "UPDATE")
{
SqlParameter parmIdx = new SqlParameter("@Idx", SqlDbType.Int);
parmIdx.Value = TxtIdx.Text;
cmd.Parameters.Add(parmIdx);
}
cmd.ExecuteNonQuery(); // 쿼리값을 돌려받지 않으니까 ExecuteNonQuery을 써준다
}
}
// 삭제 버튼 클릭 이벤트
private void BtnDelete_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(TxtIdx.Text) || string.IsNullOrEmpty(TxtAuthor.Text))
{
MetroMessageBox.Show(this, "빈 값은 삭제할 수 없습니다", "경고",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
DeleteProcess();
UpdateData();
ClearTextControls();
}
// 삭제 메서드
private void DeleteProcess()
{
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "DELETE FROM dbo.divtbl WHERE Division = @Division ";
SqlParameter parmDivision = new SqlParameter("@Division", SqlDbType.Char, 4);
parmDivision.Value = TxtIdx.Text;
cmd.Parameters.Add(parmDivision);
cmd.ExecuteNonQuery();
}
}
private void UpdateData()
{
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open(); // DB 열기
string strQuery = "SELECT b.Idx, b.Author, b.Division, " +
" d.Names AS '장르', b.Names, b.ReleaseDate, b.ISBN, " +
" REPLACE(CONVERT(VARCHAR, CONVERT(Money, b.Price), 1), '.00', '') AS Price " +
" FROM dbo.bookstbl AS b " +
" INNER JOIN dbo.divtbl AS d " +
" ON b.Division = d.Division ";
//SqlCommand cmd = new SqlCommand(strQuery, conn);
SqlDataAdapter dataAdapter = new SqlDataAdapter(strQuery, conn);
DataSet ds = new DataSet();
dataAdapter.Fill(ds, "bookstbl");
GrdBooksTbl.DataSource = ds;
GrdBooksTbl.DataMember = "bookstbl";
}
DataGridViewColumn column = GrdBooksTbl.Columns[1]; // 컬럼
column.Visible = false;
}
// 버튼을 클릭했을때 빈칸으로 만들어주는 메서드
private void ClearTextControls() // 중복된 코드를 메서드로 묶어주기
{
TxtIdx.Text = TxtAuthor.Text = TxtName.Text = TxtISBN.Text = TxtPrice.Text = "";
CboDivision.SelectedIndex = -1; // 콤보박스를 빈칸으로 해줌(초기화)
TxtIdx.ReadOnly = true;
TxtIdx.BackColor = Color.Beige;
// DateTimePicker
DtpReleaseDate.CustomFormat = " ";
DtpReleaseDate.Format = DateTimePickerFormat.Custom;
TxtName.Focus();
}
private void TxtNames_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
BtnSave_Click(sender, new EventArgs());
}
}
private void MemberForm_Load(object sender, EventArgs e)
{
DtpReleaseDate.CustomFormat = "yyyy-MM-dd";
DtpReleaseDate.Format = DateTimePickerFormat.Custom;
UpdateData(); // 데이터그리드 DB 데이터 로딩하기
UpdateCboDivision();
}
private void UpdateCboDivision()
{
using (SqlConnection conn = new SqlConnection(Commons.COONSTRING))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT Division, Names FROM dbo.divtbl";// SQL데이터를 리더에 가져옴
SqlDataReader reader = cmd.ExecuteReader(); // 하나씩 읽어줌
Dictionary<string, string> temps = new Dictionary<string, string>(); // <키, 값> (사전처럼 단어와 뜻이 있는 것을 생각)
while (reader.Read())
{
temps.Add(reader[0].ToString(), reader[1].ToString());
}
CboDivision.DataSource = new BindingSource(temps, null);
CboDivision.DisplayMember = "Value";
CboDivision.ValueMember = "Key";
CboDivision.SelectedIndex = -1;
}
}
private void DtpReleaseDate_ValueChanged(object sender, EventArgs e)
{
DtpReleaseDate.CustomFormat = "yyyy-MM-dd";
DtpReleaseDate.Format = DateTimePickerFormat.Custom;
}
}
}
먼저 관리자로 로그인 한 다음에 메인메뉴에서 책 관리로 들어간다.
텍스트박스에 빈칸인채로 저장을 누르면 에러가 뜨는 메세지를 출력하게했다.
테이블에서 데이터를 클릭하면 오른쪽 텍스트박스에 테이블값들이 출력되도록 구현했고 데이터값을 수정해서 저장버튼을 클릭하면 수정할 수 있도록 되어있다.
새 데이터를 입력하려면 신규버튼을 누른다.(이때 텍스트박스들은 전부 빈칸이 된다) 신규버튼을 누르고 각 텍스트 박스에 데이터를 넣고 저장버튼을 클릭하면 제일 최근 Idx에 확인을하면 새 데이터(홍길동전)이 저장 되어있는 것을 확인할 수 있다.
'개발자과정준비 > WinForm' 카테고리의 다른 글
[WinForm] 윈폼 소코반 만들기(푸쉬푸쉬 게임 만들기) (0) | 2020.07.20 |
---|---|
[WinForm] 윈폼과 DB연동 - 북렌탈샵 (0) | 2020.07.14 |
[WinForm] 5. 윈폼과 SSMS 연동(2) 로그인폼 구현 (0) | 2020.06.21 |
[WinForm] 4. Chart 컨트롤, 윈폼과 SSMS 연동하기 (0) | 2020.06.18 |
[WinForm] 3. 메뉴, 리스트 뷰, 트리뷰, 프로그레스바, 타이머, 그래픽, 도형 구조체, Color 구조체, Pen 클래스 (0) | 2020.06.18 |