이 프로그램은 한빛아카데미, IT CookBook C# 프로그래밍, 윤인성저의 13장 예제를 구현하였음
몇가지 책과 다른 점이 있음
- DataGridView의 이벤트를 책에서는 CurrentCellChanged() 이벤트를 사용하였으나 여기서는 CellClick()을 사용함. CurrentCellChanged() 이벤트를 사용할 경우 에러 나옴
- Form3.cs 구현에서 람다를 사용하여 button1_Click += (sender, e) => 로 사용했으나 여기서는 btnInsert_Click() 식으로 코딩함
- 기타 각 창을 끝내는 단추를 삽입하고, 대여자 숫자의 변경을 반영하는 등 약간 수정하였음
(주의)
- XML 파일(Books.xml, Users.xml)이 ./bin/Debug/에 있어야 함
- 또한 이 파일들에 데이터가 하나씩이라도 들어가 있어야 함
- XML이 조금이라도 틀리면 에러가 생김
전체 프로그램은 3개의 폼으로 구성되어 있음(Form1, Form2, Form3)
또한 3개의 클래스를 각각 다른 파일에 정의하였음
우선, 3개의 클래스를 살펴보면 다음과 같음
1. Book.cs : Book 클래스를 정의한 파일
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using System; namespace BookManager { class Book { public string Isbn { get; set; } public string Name { get; set; } public string Publisher { get; set; } public int Page { get; set; } public int UserId { get; set; } public string UserName { get; set; } public bool IsBorrowed { get; set; } public DateTime BorrowedAt { get; set; } } } | cs |
2. User.cs : User클래스를 정의한 파일
12345678 namespace BookManager{class User{public int Id { get; set; }public string Name { get; set; }}}cs 3. DataManager.cs : DataManager 클래스를 정의한 파일
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 using System;using System.Collections.Generic;using System.Linq;using System.IO; // FileLoad...using System.Xml.Linq; // XMLnamespace BookManager{class DataManager{public static List<Book> Books = new List<Book>();public static List<User> Users = new List<User>();static DataManager(){Load();}private static void Load(){try{string booksOutput = File.ReadAllText(@"./Books.xml");XElement booksXElement = XElement.Parse(booksOutput);Books = (from item in booksXElement.Descendants("book")select new Book(){Isbn = item.Element("isbn").Value,Name = item.Element("name").Value,Publisher = item.Element("publisher").Value,Page = int.Parse(item.Element("page").Value),BorrowedAt = DateTime.Parse(item.Element("borrowedAt").Value),IsBorrowed = item.Element("isBorrowed").Value != "0" ? true : false,UserId = int.Parse(item.Element("userId").Value),UserName = item.Element("userName").Value}).ToList<Book>();string usersOutput = File.ReadAllText(@"./Users.xml");XElement usersXElement = XElement.Parse(usersOutput);Users = (from item in usersXElement.Descendants("user")select new User(){Id = int.Parse(item.Element("id").Value),Name = item.Element("name").Value}).ToList<User>();}catch (FileLoadException ex){Save();}}public static void Save(){string booksOutput = "";booksOutput += "<Books>\n";foreach (var item in Books){booksOutput += "<book>\n";booksOutput += " <isbn>" + item.Isbn + "</isbn>\n";booksOutput += " <name>" + item.Name + "</name>\n";booksOutput += " <publisher>" + item.Publisher + "</publisher>\n";booksOutput += " <page>" + item.Page + "</page>\n";booksOutput += " <borrowedAt>" + item.BorrowedAt.ToLongDateString() + "</borrowedAt>\n";booksOutput += " <isBorrowed>" + (item.IsBorrowed ? 1 : 0) + "</isBorrowed>\n";booksOutput += " <userId>" + item.UserId + "</userId>\n";booksOutput += " <userName>" + item.UserName + "</userName>\n";booksOutput += "</book>\n";}booksOutput += "</Books>\n";string usersOutput = "";usersOutput += "<users>\n";foreach (var item in Users){usersOutput += "<user>\n";usersOutput += " <id>" + item.Id + "</id>\n";usersOutput += " <name>" + item.Name + "</name>\n";usersOutput += "</user>\n";}usersOutput += "</users>\n";File.WriteAllText(@"./Books.xml", booksOutput);File.WriteAllText(@"./Users.xml", usersOutput);}}}cs Load()는 DataManager 클래스의 생성자에서 호출한다. Books.xml 파일을 읽어 XML Parsing을 하는 메소드이다.25번 줄을 보면 읽은 값은 Linq 를 사용하여 Books<book> 리스트에 저장된다.또 같은 방법으로 ./Users.xml 파일을 읽어 Users<User> 리스트를 만든다. XML 파서는 string으로 부터 처리한다.XML 파일은 다음과 같은 모습으로 저장된다. 처음에 하나 이상의 데이터를 만들어 두어야 에러없이 프로그램이 수행된다.Books.XML
123456789101112 <books><book><isbn>9791156641452</isbn><name>IT CookBook 실전에 강한 PLC</name><publisher>한빛아카데미</publisher><page>384</page><borrowedAt>0001년 1월 1일 월요일</borrowedAt><isBorrowed>0</isBorrowed><userId>0</userId><userName></userName></book></books>cs Users.XML
12345678910 <users><user><id>1</id><name>연하진</name></user><user><id>2</id><name>윤인성</name></user></users>cs Form1은 다음과 같이 디자인 한다.
DataGridView는 2개가 있는데, 각각 Books<Book>과 Users<User>를 연결한다.
이를 위해 데이터 소스 창에서 "개체"를 선택하고 다음을 누른 후, BookManager 아래에 있는 Book과 User를 선택해준다.
그림으로 보자. 단, 이를 위해서는 일단 한번 빌드를 해서 클래스들이 있음을 알아야 한다.
이렇게 하면 데이터 소스창이 다음과 같이 보인다.
도서관리 폼인 Form2는 다음과 같이 디자인한다.
사용자관리 폼인 Form3는 다음과 같이 디자인한다.
소스를 살펴보자. Form1.cs는 다음과 같다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 using System;using System.Data;using System.Linq;using System.Windows.Forms;namespace BookManager{public partial class Form1 : Form{public Form1(){InitializeComponent();Text = "도서관 관리";// 레이블 설정label5.Text = DataManager.Books.Count.ToString();label6.Text = DataManager.Users.Count.ToString();label7.Text = DataManager.Books.Where((x) => x.IsBorrowed).Count().ToString();label8.Text = DataManager.Books.Where((x) =>{ return x.IsBorrowed && x.BorrowedAt.AddDays(7) < DateTime.Now; }).Count().ToString();// 데이터 그리드 설정dataGridView1.DataSource = DataManager.Books;dataGridView2.DataSource = DataManager.Users;}// 대여 버튼 클릭private void btnBorrow_Click(object sender, EventArgs e){if (txtIsbn.Text == "")MessageBox.Show("Isbn을 입력해주세요");else if (txtUserId.Text == "")MessageBox.Show("사용자 Id를 입력해주세요");else{Book book = DataManager.Books.Single((x) => x.Isbn == txtIsbn.Text);if (book.IsBorrowed)MessageBox.Show("이미 대여 중인 도서입니다");else{User user = DataManager.Users.Single((x) => x.Id.ToString() == txtUserId.Text);book.UserId = user.Id;book.UserName = user.Name;book.IsBorrowed = true;book.BorrowedAt = DateTime.Now;dataGridView1.DataSource = null;dataGridView1.DataSource = DataManager.Books;DataManager.Save();MessageBox.Show("/" + book.Name + "/이 " + user.Name + "/님께 대여되었습니다");// 대여자 숫자 표시 변경label7.Text = DataManager.Books.Where((x) => x.IsBorrowed).Count().ToString();}}}// 반납 버튼 클릭private void btnReturn_Click(object sender, EventArgs e){if (txtIsbn.Text == "")MessageBox.Show("Isbn을 입력해주세요");else{// DataManager.Books 에서 Isbn이 txtIsbn과 같은 객체 하나를 추출하여 book 이라 한다Book book = DataManager.Books.Single((x) => x.Isbn == txtIsbn.Text);if (book.IsBorrowed){// 사용자Id, 즉 txtUserId 와 관계없이 책을 반납함User user = DataManager.Users.Single((x) => x.Id.ToString() == book.UserId.ToString());book.UserId = 0;book.UserName = "";book.IsBorrowed = false;book.BorrowedAt = new DateTime();dataGridView1.DataSource = null;dataGridView1.DataSource = DataManager.Books;DataManager.Save();if (book.BorrowedAt.AddDays(7) > DateTime.Now)MessageBox.Show("/" + book.Name + "/이 연체 상태로 반납되었습니다");elseMessageBox.Show("/" + book.Name + "/이 반납되었습니다");// 대여자 숫자 표시 변경label7.Text = DataManager.Books.Where((x) => x.IsBorrowed).Count().ToString();}elseMessageBox.Show("대여 상태가 아닙니다");}}// Books DataGridViewprivate void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e){try{Book book = dataGridView1.CurrentRow.DataBoundItem as Book;txtIsbn.Text = book.Isbn;txtName.Text = book.Name;}catch (Exception ex){MessageBox.Show(ex.Message);}}// Users DataGridViewprivate void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e){try{User user = dataGridView2.CurrentRow.DataBoundItem as User;txtUserId.Text = user.Id.ToString();}catch (Exception ex){MessageBox.Show(ex.Message);}}// 도서관리 메뉴private void 도서관리ToolStripMenuItem_Click(object sender, EventArgs e){Form form = new Form2();form.ShowDialog();}// 사용자 관리 메뉴private void 사용자관리ToolStripMenuItem_Click(object sender, EventArgs e){new Form3().ShowDialog();}private void 끝내기ToolStripMenuItem_Click(object sender, EventArgs e){this.Close();}}}cs
Form2.cs는 도서관리를 위한 프로그램으로 다음과 같다.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 using System;using System.Linq;using System.Windows.Forms;namespace BookManager{public partial class Form2 : Form{public Form2(){InitializeComponent();dgvBooks.DataSource = DataManager.Books;}// dataGridView에서 셀이 클릭되면...private void dgvBooks_CellClick(object sender, DataGridViewCellEventArgs e){Book book = dgvBooks.CurrentRow.DataBoundItem as Book;txtIsbn.Text = book.Isbn;txtName.Text = book.Name;txtPage.Text = book.Page.ToString();txtPublisher.Text = book.Publisher;}// 추가private void btnInsert_Click(object sender, EventArgs e){if (DataManager.Books.Exists((x) => x.Isbn == txtIsbn.Text))MessageBox.Show("이미 존재하는 도서입니다");else{Book book = new Book();book.Isbn = txtIsbn.Text;book.Name = txtName.Text;book.Publisher = txtPublisher.Text;book.Page = int.Parse(txtPage.Text);DataManager.Books.Add(book);dgvBooks.DataSource = null;dgvBooks.DataSource = DataManager.Books;DataManager.Save();}}// 수정private void btnModify_Click(object sender, EventArgs e){if (txtIsbn.Text == "")MessageBox.Show("Isbn을 입력해야 합니다");else{Book book = DataManager.Books.Single((x) => x.Isbn == txtIsbn.Text);book.Name = txtName.Text;book.Publisher = txtPublisher.Text;book.Page = int.Parse(txtPage.Text);dgvBooks.DataSource = null;dgvBooks.DataSource = DataManager.Books;DataManager.Save();}}// 삭제private void btnDelete_Click(object sender, EventArgs e){if (txtIsbn.Text == "")MessageBox.Show("Isbn을 입력해야 합니다");else{Book book = DataManager.Books.Single((x) => x.Isbn == txtIsbn.Text);DataManager.Books.Remove(book);dgvBooks.DataSource = null;dgvBooks.DataSource = DataManager.Books;DataManager.Save();}}private void btnClose_Click(object sender, EventArgs e){this.Close();}}}cs
Form3.cs는 사용자관리를 위한 프로그램으로 다음과 같다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 using System;using System.Linq;using System.Windows.Forms;namespace BookManager{public partial class Form3 : Form{public Form3(){InitializeComponent();dgvUser.DataSource = DataManager.Users;}// 추가private void btnAdd_Click(object sender, EventArgs e){if (txtUserId.Text == "")MessageBox.Show("Id를 입력해야 합니다");else if (DataManager.Users.Exists((x) => int.Parse(txtUserId.Text) == x.Id))MessageBox.Show("사용자 Id 가 겹칩니다");else{User user = new User();user.Id = int.Parse(txtUserId.Text);user.Name = txtName.Text;DataManager.Users.Add(user);dgvUser.DataSource = null;dgvUser.DataSource = DataManager.Users;DataManager.Save();}}// 수정private void btnUpdate_Click(object sender, EventArgs e){User user = DataManager.Users.Single((x) => int.Parse(txtUserId.Text) == x.Id);user.Name = txtName.Text;dgvUser.DataSource = null;dgvUser.DataSource = DataManager.Users;}// 삭제private void btnDelete_Click(object sender, EventArgs e){User user = DataManager.Users.Single((x) => int.Parse(txtUserId.Text) == x.Id);DataManager.Users.Remove(user);dgvUser.DataSource = null;dgvUser.DataSource = DataManager.Users;}private void btnClose_Click(object sender, EventArgs e){this.Close();}}}cs
프로그램의 실행 화면 중 첫번째 창은 다음과 같다.
데이터베이스를 사용하지 않고 XML을 사용하여 데이터를 관리하는 프로그램은 이 프로그램을 기준으로 만들 수 있을 것이다.
Beeeye Dmu
'C# Form' 카테고리의 다른 글
[C# Form] 마우스 좌표를 StatusStrip에 표시 (0) | 2016.09.21 |
---|---|
[C# Form] 간단한 디지털 시계 (0) | 2016.09.21 |
Show()와 ShowDialog() (1) | 2016.09.18 |
C# DateTimePicker의 값을 DB에 넣는 방법(동영상 링크 포함) (0) | 2016.06.14 |
Fully C# Save, Insert, Update, Delete, View, Search, Clear in Visual studio (0) | 2016.06.13 |