C# 포트폴리오 도전기(1-4. 메인 폼 UI 구현)

min seung moon·2021년 8월 19일
0

C# 포트폴리오

목록 보기
5/10
post-thumbnail
post-custom-banner

1. 메인 폼 UI 구현

01. 구성

  • 메뉴
    • 홈(관리자, 직원, 고객)
      • 조회, 비밀번호변경, 종료
    • 회원관리(관리자)
      • 조회, 추가, 수정, 삭제
    • 도서관리(관리자, 직원)
      • 조회, 추가, 수정, 삭제, 검색
    • rental & return (관리자, 직원, 고객)
      • 렌탈조회, 연체자조회, 렌탈등록, 반납확인, 기록조회

02. UI Control

-1. RibbonControl

  • 리본 컨트롤을 사용할 예정입니다
  • 일단 메뉴만 먼저 만들고 메인은 어떤 내용이냐에 따라 추가할 예정입니다!
  • RibbonControl 추가 후에 Main Form Control 속성에 isMidContainer 속성을 true로 바꿔주세요!
  • 그리고 실행을 해보면 탭메뉴 옆에 파일 메뉴가 기본적으로 있고 클릭해도 안되요!
    • 하지만 나는 필요가 없다 삭제하고 싶다면 RibbonControl 속성에 showApplicationButton을 flase로 바꿔주세요!
  • 그리고 저는 모든 메뉴 모든 버튼에 LargeWidth 속성에 60을 줄거에요!

-2. 홈 메뉴

  • 조회, 비밀번호변경, 종료 버튼을 추가할 예정이구요!
  • 버튼은 그룹에 있는 추가 버튼으로 추가해서 캡션이랑 이미지 설정해서 만들예정입니다
  • Page
    • home_page
  • Group
    • 메인, 기타
    • home_main_group, home_other_group
  • Button
    • 조회, 비밀번호 변경, 종료
    • home_reset_btn, home_changePassword_btn, home_close_btn

-3. 회원 관리 메뉴

  • Page
    • 회원 관리
    • user_page
  • Group
    • 메인
    • user_main_group
  • Button
    • 회원조회, 회원등록, 회원수정, 회원삭제, 회원검색
    • user_reset_btn, user_add_btn, user_update_btn, user_delete_btn, user_search_btn

-4. 도서 관리 메뉴

  • Page
    • 도서 관리
    • book_page
  • Group
    • 메인
    • book_main_group
  • Button
    • 도서조회, 도서등록, 도서수정, 도서삭제, 도서검색
    • book_reset_btn, book_add_btn, book_update_btn, book_delete_btn, book_search_btn

-5. 렌탈 & 반납 메뉴

  • Page
    • 렌탈 & 반납
    • rental_page
  • Group
    • 메인
    • rental_main_group
  • Button
    • 렌탈조회, 연제차조회, 렌탈등록, 반납확인, 기록조회
    • rental_reset_btn, overdue_reset_btn, rental_add_btn, rental_return_btn, rental_log_btn

2. 간단 기능 해결

01. Enter 로그인

  • 계속 로그인을 할려고 하는데 버튼 누르거나 버튼까지 tab을 눌러서 이동하기가 귀찮더라구요!
  • 그래서 비밀번호 텍스트창에서 키업을 했을때 enter키면 로그인이 되도록 할거에요!
  • 그럴 경우 로그인 버튼에 있던 코드를 메서드 추출해줘야 겠죠!
    • doLogin으로 추출할게요!
using BookManagementProgram.Repository;
using System;
using System.Linq;
using System.Windows.Forms;

namespace BookManagementProgram.LOGIN
{
    public partial class Login : Form
    {
        BookUserRepository userRepository = new BookUserRepository();
        public Login()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;

            if(Properties.Settings.Default.isLoginIdSave)
            {
                id_txt.Text = Properties.Settings.Default.LoginId;
                idSaveCheck_chk.Checked = Properties.Settings.Default.isLoginIdSave;
            }
        }

        // TextBox Focussing
        private void label1_Click(object sender, EventArgs e)
        {
            id_txt.Focus();
        }
        private void label2_Click(object sender, EventArgs e)
        {
            pw_txt.Focus();
        }

        // 비밀번호 보이기 체크박스
        private void showPassword_chk_CheckedChanged(object sender, EventArgs e)
        {
            if (showPassword_chk.Checked)
                pw_txt.PasswordChar = default(char);
            else
                pw_txt.PasswordChar = '*';
        }

        // 아이디 저장 체크박스
        private static void NotSaveID()
        {
            Properties.Settings.Default.isLoginIdSave = false;
            Properties.Settings.Default.Save();
        }
        private void SaveID()
        {
            Properties.Settings.Default.LoginId = id_txt.Text;
            Properties.Settings.Default.isLoginIdSave = true;
            Properties.Settings.Default.Save();
        }

        // 아이디 찾기 라벨
        private void findId_lbl_Click(object sender, EventArgs e)
        {
            (new FindById()).ShowDialog();
        }
        // 비밀번호 찾기 라벨
        private void findPassword_lbl_Click(object sender, EventArgs e)
        {
            (new FindByPassword()).ShowDialog();
        }

        // 로그인 버튼
        private void login_btn_Click(object sender, EventArgs e)
        {
            doLogin();
        }

        // 비밀번호 텍스트 창
        private void pw_txt_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                doLogin();
            }
        }

        private void doLogin()
        {
            if (string.IsNullOrEmpty(id_txt.Text))
            {
                MessageBox.Show("아이디를 입력해주세요.");
                id_txt.Focus();
                return;
            }
            if (string.IsNullOrEmpty(pw_txt.Text))
            {
                MessageBox.Show("비밀번호를 입력해주세요.");
                pw_txt.Focus();
                return;
            }

            string result = userRepository.Login(id_txt.Text, pw_txt.Text);
            if (!result.All(char.IsDigit))
            {
                MessageBox.Show(result);
                return;
            }

            if (!userRepository.InsertLoginLog())
            {
                MessageBox.Show("인터넷을 연결해주세요.");
                return;
            }

            if (idSaveCheck_chk.Checked)
            {
                SaveID();
            }
            else
            {
                NotSaveID();
            }

            Main main = new Main();
            main.Show();
            main.BringToFront();

            this.Hide();
        }

    }
}

02. 메인 폼 클로즈 버튼

  • 간단하니까 빠르게 끊을 내도록 하죠!
    • 나가는건 로그를 안찍을 꺼라 그냥 application 꺼주는걸로 끝낼께요!
using BookManagementProgram.LOGIN;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BookManagementProgram
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }
        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void home_close_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Application.Exit();
        }

    }
}

03. 메인 비밀번호 변경 버튼

  • 이것도 이미 구현한 FindByPassword를 사용할거에요!
    • 그렇기 때문에 Form만 불러주면 되겠죠!
using BookManagementProgram.LOGIN;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BookManagementProgram
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
        }
        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void home_close_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Application.Exit();
        }

        private void home_changePassword_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            (new FindByPassword()).ShowDialog();
        }
    }
}

3. 수정 및 메뉴 Visible 설정

01. authority_name과 grade_name을 no으로 변경

  • 메뉴 visible 작업을 하면서 생각이 든게 이름으로 받으면 작성할게 많구나 싶어서 그냥 번호로받아서 필요할 때 이름으로 바꿀게요!

-1. DB / PROCUDURE / BOOK_LOGIN_S1

USE [BookManagement]
GO
/****** Object:  StoredProcedure [dbo].[BOOK_LOGIN_S1]    Script Date: 2021-08-19 오후 6:12:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<문민승>
-- Create date: <2021.08.19,>
-- Description:	<도서관리 프로그램 로그인>
-- =============================================
ALTER PROCEDURE [dbo].[BOOK_LOGIN_S1]
	@USER_ID	NVARCHAR(20)
	,@USER_PW	CHAR(64)
AS
BEGIN
	SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
	
    IF NOT EXISTS
	(
		SELECT	user_no
		FROM	Book_User_LogIn
		WHERE	user_id	=	@USER_ID
		AND		user_pw	=	@USER_PW
	)
	BEGIN
		RAISERROR('존재하지 않는 사용자 입니다.',16,1)
		RETURN
	END

	SELECT	l.user_no, i.user_name, i.user_address, i.user_birth, l.user_id, l.user_pw, l.register_date, a.authority_no, g.grade_no
	FROM			Book_User_LogIn	as l
	INNER JOIN		Book_User_Info	as i
	ON				l.user_no = i.user_no
	INNER JOIN		Book_User_Auth	as a
	ON				l.authority_no = a.authority_no
	INNER JOIN		Book_User_Grade	as g
	ON				l.grade_no = g.grade_no
	WHERE	user_id	=	@USER_ID
	AND		user_pw	=	@USER_PW
END

-2. Model / User.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BookManagementProgram.Model
{
    class User
    {
        private string user_no;
        private string user_name;
        private string user_address;
        private string user_birth;
        private string user_id;
        private string user_pw;
        private string register_date;
        private int authority_no;
        private int grade_no;

        public string userNo { get { return user_no; } set { user_no = value; } }
        public string userName { get { return user_name; } set { user_name = value; } }
        public string userAddress { get { return user_address; } set { user_address = value; } }
        public string userBirth { get { return user_birth; } set { user_birth = value; } }
        public string userId { get { return user_id; } set { user_id = value; } }
        public string userPw { get { return user_pw; } set { user_pw = value; } }
        public string registerDate { get { return register_date; } set { register_date = value; } }
        public int authorityNo { get { return authority_no; } set { authority_no = value; } }
        public int gradeNo { get { return grade_no; } set { grade_no = value; } }

        public User(string user_no, string user_name, string user_address, string user_birth, string user_id, string user_pw, string register_date, int authority_no, int grade_no)
        {
            this.user_no = user_no;
            this.user_name = user_name;
            this.user_address = user_address;
            this.user_birth = user_birth;
            this.user_id = user_id;
            this.user_pw = user_pw;
            this.register_date = register_date;
            this.authority_no = authority_no;
            this.grade_no = grade_no;
        }

        public User()
        {
        }
    }
}

-3. Repository / BookUserRepository.cs

using BookManagementProgram.Model;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;

namespace BookManagementProgram.Repository
{
    class BookUserRepository : IBookUserRepository
    {
        private SqlConnection conn = null;
        private SqlCommand cmd = null;
        public static List<User> userList = null;
        public static User user = null;

        public BookUserRepository()
        {
            conn = DBConn.DBConn.getConn();
            cmd = new SqlCommand();
            cmd.Connection = conn;
        }

        // 로그인 로직
        public string Login(string userId, string userPw)
        {
            try
            {
                string sql = $"EXEC BOOK_LOGIN_S1 @USER_ID = '{userId}', @USER_PW = '{Encryption(userPw)}';";

                cmd.CommandText = sql;
                conn.Open();

                // 데이터 출력
                using (SqlDataReader SR = cmd.ExecuteReader())
                {
                    while (SR.Read())
                    {
                        user = new User(
                            SR[0].ToString()
                            , SR[1].ToString()
                            , SR[2].ToString()
                            , SR[3].ToString()
                            , SR[4].ToString()
                            , SR[5].ToString()
                            , SR[6].ToString()
                            , (int)SR[7]
                            , (int)SR[8]
                            );
                    }
                    SR.Close();
                }

                return user.userNo;
            }
            catch(SqlException e)
            {
                return e.Message;
            }
            finally
            {
                conn.Close();
            }
        }

        // SHA256 암호화 메서드
        public static string Encryption(string data)
        {
            SHA256 sha = new SHA256Managed();
            byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
            StringBuilder stringBuilder = new StringBuilder();
            foreach (byte b in hash)
            {
                stringBuilder.AppendFormat("{0:x2}", b);
            }
            return stringBuilder.ToString();
        }

        // 아이디 찾기 로직
        public string FindById(string userNo, string userName)
        {
            try
            {
                string sql = $"EXEC BOOK_LOGIN_S2 @USER_NO = {userNo}, @USER_NAME = '{userName}';";
                string user_id = string.Empty;

                cmd.CommandText = sql;
                conn.Open();

                // 데이터 출력
                using (SqlDataReader SR = cmd.ExecuteReader())
                {
                    while (SR.Read())
                    {
                        user_id = SR[0].ToString();
                    }
                    SR.Close();
                }

                return $"아이디 : {user_id} 입니다.";
            }
            catch (SqlException e)
            {
                return e.Message;
            }
            finally
            {
                conn.Close();
            }
        }

        // 비밀번호 찾기 로직
        public bool FindByPassword(string userNo, string userId, string newPassword)
        {
            try
            {
                string sql = $"EXEC BOOK_LOGIN_U1 @USER_NO = {userNo}, @USER_ID = '{userId}', @NEW_PW = '{Encryption(newPassword)}';";

                cmd.CommandText = sql;
                conn.Open();

                return cmd.ExecuteNonQuery() > 0 ? true : false;
            }
            catch (SqlException e)
            {
                return false;
            }
            finally
            {
                conn.Close();
            }
        }

        public bool InsertLoginLog()
        {
            try
            {
                string sql = $"EXEC BOOK_LOGIN_I1 @USER_NO = {user.userNo}, @USER_ID = '{user.userId}', @ENTER_IP = '{GetExternalIPAddress()}';";

                cmd.CommandText = sql;
                conn.Open();

                return cmd.ExecuteNonQuery() > 0 ? true : false;
            }
            catch (SqlException e)
            {
                return false;
            }
            finally
            {
                conn.Close();
            }
        }

        // 외부 IP
        public static string GetExternalIPAddress()
        {
            string externalip = new WebClient().DownloadString("http://ipinfo.io/ip").Trim();

            return externalip ?? GetInternalIPAddress();//null경우 내부 IP 반환;
        }

        // 내부
        // DNS, 단순 도메인 이름 확인 기능이 제공
        // GetGostEntity, 호스트 이름 또는 IP 주소를 IPHostEntry 인스턴스로 확인
        // GetHostName, 로컬 컴퓨터의 호스트 이름을 가져온다
        public static string GetInternalIPAddress()
        {
            var host = Dns.GetHostEntry(Dns.GetHostName());

            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    return ip.ToString();
                }
            }

            throw new Exception("인터넷 연결 없음");
        }
    }
}

02. 메뉴 Visible

  • 상단에 구성한 대로 권한에 따라 메뉴를 보이게 안보이게 할게요!
  • 이런 경우에는 if...else 문보다 switch문이 간결하다는 사실!
    • 솔직히 취향이지만요!
using BookManagementProgram.LOGIN;
using BookManagementProgram.Model;
using  BookManagementProgram.Repository;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BookManagementProgram
{
    public partial class Main : Form
    {
        User user = BookUserRepository.user;

        public Main()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;

            switch(user.authorityNo)
            {
                case 0:
                    user_page.Visible = true;
                    book_page.Visible = true;
                    rental_page.Visible = true;
                    break;
                case 1:
                    book_page.Visible = true;
                    rental_page.Visible = true;
                    break;
                case 2:
                    rental_page.Visible = true;
                    break;
            }
        }
        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void home_close_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Application.Exit();
        }

        private void home_changePassword_btn_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            (new FindByPassword()).ShowDialog();
        }
    }
}

profile
아직까지는 코린이!
post-custom-banner

0개의 댓글