본문 바로가기

C# WPF

[C# WPF]Access DB를 이용한 전화번호부 프로그램(ListBox 사용)

아래 그림과 같이 추가, 삭제, 업데이트, 검색이 가능한 데이터베이스 WPF 프로그램을 만들어보겠습니다. ListBox를 사용하겠습니다.


먼저 데이터베이스를 연결하기 위해서 Visual Studio의 [보기] 메뉴에서 [서버탐색기]를 선택합니다.


데이터 연결 메뉴에 마우스 오른쪽 버튼을 누르면 연결추가 창이 뜨고 여기에 데이터 소스를 Microsoft Access 데이터베이스 파일(OLE DB)를 선택하고 데이터베이스 파일 이름을 찾아보기 버튼을 눌러서 선택합니다. 여기에서는 myStudent.accdb 파일을 선택했습니다. 테스트를 위해 myStudent.accdb 파일에 몇개의 레코드를 넣어두었습니다.




연결테스트를 눌러 연결이 되었는지를 확인한 후, 확인 버튼을 누르면 아래 그림과 같이 DB가 연결되었음을 알 수 있습니다.



이 과정을 통해 프로그램과 DB는 binding 됩니다.

맨 위의 그림과 같이 디자인을 합니다. lbStudent 라는 ListBox가 있고, 4개의 Label과 4개의 TextBox를 사용헀습니다. 5개의 버튼으로 추가, 삭제, 업데이트, 검색, 종료 명령을 수행합니다. XAML 파일은 다음과 같습니다.

<Window

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:local="clr-namespace:accDB" x:Class="accDB.MainWindow"

        Title="MainWindow" Height="350" Width="525" >

    <Window.Resources>

        <local:myStudentDataSet x:Key="myStudentDataSet"/>

        <CollectionViewSource x:Key="studentViewSource" Source="{Binding Student, Source={StaticResource myStudentDataSet}}"/>

    </Window.Resources>

    <Grid DataContext="{StaticResource studentViewSource}" Margin="0,0,0,-30" Height="350" VerticalAlignment="Top">

        <ListBox x:Name="lbStudent" HorizontalAlignment="Left" Height="159" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" MouseLeftButtonUp="lbStudent_MouseLeftButtonUp"/>

        <Label Content="학번" HorizontalAlignment="Left" Margin="10,215,0,0" VerticalAlignment="Top"/>

        <Label Content="이름" HorizontalAlignment="Left" Margin="10,246,0,0" VerticalAlignment="Top"/>

        <Label Content="전화" HorizontalAlignment="Left" Margin="10,277,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.487,1.692"/>

        <Label Content="순번" HorizontalAlignment="Left" Margin="10,184,0,0" VerticalAlignment="Top"/>

        <TextBox Name="txtID" HorizontalAlignment="Left" Height="23" Margin="65,187,0,0" VerticalAlignment="Top" Width="120"/>

        <TextBox Name="txtNumber" HorizontalAlignment="Left" Height="23" Margin="65,218,0,0" VerticalAlignment="Top" Width="120"/>

        <TextBox Name="txtName" HorizontalAlignment="Left" Height="23" Margin="65,249,0,0" VerticalAlignment="Top" Width="120"/>

        <TextBox Name="txtPhone" HorizontalAlignment="Left" Height="23" Margin="65,280,0,0" VerticalAlignment="Top" Width="120"/>

        <Button Name="btnInsert" Content="추가" HorizontalAlignment="Left" Margin="207,219,0,0" VerticalAlignment="Top" Width="75" Click="btnInsert_Click"/>

        <Button Name="btnDelete" Content="삭제" HorizontalAlignment="Left" Margin="297,219,0,0" VerticalAlignment="Top" Width="75" Click="btnDelete_Click"/>

        <Button Content="업데이트" HorizontalAlignment="Left" Margin="390,219,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>

        <Button Name="btnSearch" Content="검색" HorizontalAlignment="Left" Margin="207,250,0,0" VerticalAlignment="Top" Width="75" Click="btnSearch_Click"/>

        <Button Content="종료" HorizontalAlignment="Left" Margin="297,250,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>

    </Grid>

</Window>

이제는 C#으로 소스코드를 작성할 차례입니다.

먼저 using 구문에 다음과 같이 OleDb를 추가합니다.

using System.Data.OleDb;


    public partial class MainWindow : Window

    {

        OleDbConnection conn = null;

        OleDbCommand cmd = null;

        OleDbDataReader reader = null;

        string connstr = null;


        public MainWindow()

        {

            InitializeComponent();

            DisplaylbStudent();

        }

    ...

   }


DB 연결을 위해 OleDbConnection, OleDbCommand, OleDbDataReader 변수를 선언합니다. DB 커넥션을 위해 사용될 connstr도 선언합니다.

MainWindow()의 InitializeComponent(); 밑에 DB의 내용을 읽어와서 ListBox에 보여주는 DisplaylbStudent() 함수를 호출합니다.

         private void DisplaylbStudent()

        {

            if (conn == null)

            {

                connstr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\Path\myStudent.accdb";

                conn = new OleDbConnection(connstr);

                conn.Open();

            }


            string sql = "Select * FROM Student";

            cmd = new OleDbCommand(sql, conn);

            cmd.CommandText = sql;


            reader = cmd.ExecuteReader();

            lbStudent.Items.Clear();


            while (reader.Read())

            {

                string item = "";

                item += reader["ID"].ToString() + " ";

                item += reader["StudentID"].ToString() + " ";

                item += reader["NAME"].ToString() + " ";

                item += reader["PHONE"].ToString();

                lbStudent.Items.Add(item);

            }

            reader.Close();

        }


서버탐색기에서 myStudent.accdb를 선택하고 마우스 오른쪽 버튼을 누르고 속성을 선택하면 다음과 같은 속성창이 나옵니다. 여기서 "연결 문자열"의 내용을 복사해서 connstr에 사용합니다.

connection을 열고, sql 명령어를 command를 사용하여 실행시킵니다. 여러 개의 레코드를 읽어오기 위해 ExecuteReader()를 사용합니다.

마지막에는 reader.Close()를 해주어야 합니다.



이제 프로그램을 실행하면, 리스트박스에 DB의 내용이 표시되는 것을 볼 수 있습니다. 이 중 하나를 선택하면 아래 그림과 같이 TextBox에 내용이 표시되게 하려고 합니다.



이렇게 하기 위해서 ListBox에서 마우스 이벤트가 발생하면 처리해주는 이벤트 함수를 만들겠습니다. lsStudent_MouseLeftButtonUp 함수는 다음과 같습니다.

        private void lbStudent_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)

        {

            ListBox lb = sender as ListBox;


            if (lb.SelectedItem == null)

                return;

            string[] items = lb.SelectedItem.ToString().Split(' ');

            txtID.Text = items[0];

            txtNumber.Text = items[1];

            txtName.Text = items[2];

            txtPhone.Text = items[3];

        }


업데이트 부터 코딩을 해볼까요? 텍스트박스의 내용을 바꾸고 "업데이트" 버튼을 누르면 내용이 바뀌도록 하겠습니다. 아무런 레코드가 선택되지 않은 상태에서 "업데이트"버튼을 누르면 안되니까 맨 앞에 txtID.Text == "" 인지를 확인하였습니다.

UPDATE를 위한 sql문을 만들고, connection을 열고 command를 만든 후, ExecuteNonQuery() 명령으로 UPDATE를 실행합니다. 성공적으로 명령이 실행되면 connection을 닫고, 다시 DisplaylbStudent() 함수로 DB의 내용을 리스트박스에 표시합니다. ClearTextBox() 함수는 TextBox들의 내용을 비워줍니다.

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            if (txtID.Text == "")

            {

                MessageBox.Show("업데이트할 데이터를 선택하세요", "Update Warning!!");

                return;

            }

            string sql = string.Format("UPDATE Student SET StudentID='{0}', NAME='{1}', PHONE='{2}' WHERE ID={3}",

                txtNumber.Text.ToString(), txtName.Text.ToString(), txtPhone.Text.ToString(), txtID.Text.ToString());


            if (conn == null)

            {

                conn = new OleDbConnection(connstr);

                conn.Open();

            }

            cmd = new OleDbCommand(sql, conn);


            try

            {

                int x = cmd.ExecuteNonQuery();

                if (x >= 1)

                    MessageBox.Show("정상적으로 업데이트 되었습니다", "Update Success!");

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message, "Update Error!");

            }


            conn.Close();

            conn = null;


            DisplaylbStudent();

            ClearTextBoxes();

        }


        private void ClearTextBoxes()

        {

            txtID.Text = null;

            txtNumber.Text = null;

            txtName.Text = null;

            txtPhone.Text = null;

        }

 전화번호를 010-3333-7777로 바꾸고 업데이트 버튼을 누르면 다음과 같이 바뀌는 것을 확인할 수 있습니다.

이제 새로운 레코드를 추가해보겠습니다. 

TextBox에 값을 입력하고, "추가" 버튼을 누르면 새로운 레코드가 DB에 추가되도록 하겠습니다. 

업데이트와 비슷합니다. 학번과 이름은 반드시 넣도록 했고, connection을 열고 sql을 만들고, ExecuteNonQuery()를 통해 실행합니다. 레코드가 삽입되면 connection을 닫고, 바뀐 DB의 내용을 리스트박스에 새로 표시한 후, 텍스트상자들은 비워줍니다.

       private void btnInsert_Click(object sender, RoutedEventArgs e)

        {

            if (txtName.Text == "" || txtNumber.Text == "")

            {

                MessageBox.Show("학번과 이름은 반드시 넣어야 합니다");

                return;

            }

            conn = new OleDbConnection(connstr);

            conn.Open();


            string sql = "INSERT INTO Student VALUES ('" + txtID.Text.ToString() + "', '"+txtNumber.Text.ToString()+

                "', '" + txtName.Text.ToString() +"', '" + txtPhone.Text.ToString() + "')";

            cmd = new OleDbCommand(sql, conn);


            try

            {

                int x = cmd.ExecuteNonQuery();

                if (x == 1)

                    MessageBox.Show("정상적으로 삽입되었습니다", "Insert Success!!");

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message, "Insert Failed");

            }

            finally

            {

                conn.Close();

                conn = null;

            }

            DisplaylbStudent();

            ClearTextBoxes();

        }


아래 그림에서 맨 밑에 9번 고두레가 추가된 것을 볼 수 있군요.



다음은 삭제 프로그램을 만들어보겠습니다. ListBox에서 레코드 하나를 선택하고 "삭제"버튼을 누르면 삭제되게 할 겁니다. 아래 그림처럼 9번 고두레를 선택하면 이의 내용들이 TextBox에 표시되고, 이때 "삭제"버튼을 누르면 DB에서 삭제되는 겁니다.



삭제를 위한 코드는 다음과 같습니다.

        private void btnDelete_Click(object sender, RoutedEventArgs e)

        {

            if (txtID.Text == "")

            {

                MessageBox.Show("삭제할 데이터를 선택하세요", "Delete Warning!!");

                return;

            }

            string sql = "DELETE FROM Student WHERE ID=" + txtID.Text.ToString();

            cmd = new OleDbCommand(sql, conn);

            try

            {

                int x = cmd.ExecuteNonQuery();

                if (x == 1)

                    MessageBox.Show("정상적으로 삭제되었습니다", "Delete Success!!");

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message, "Delete Failed");

            }

            DisplaylbStudent();

            ClearTextBoxes();

        }


앞의 코드들과 같은 형태입니다. 

마지막 작업은 검색입니다. 텍스트상자에 값을 입력하고 "검색"버튼을 누르면 해당하는 레코드를 찾아서 리스트박스에 표시해줍니다.



코드는 다음과 같습니다. 이름이 같은 레코드가 2개 이상 있을 수도 있으므로 ExecuteReader() 메소드를 사용합니다.

        private void btnSearch_Click(object sender, RoutedEventArgs e)

        {

            string sql = null;


            if (txtName.Text == "" && txtNumber.Text == "")

            {

                MessageBox.Show("학번이나 이름을 입력해주세요", "Search Warning!!");

                return;

            }

            if (txtName.Text != "")  // search by Name

            {

                sql = "SELECT * FROM Student WHERE NAME='" + txtName.Text.ToString() + "'";

            }

            else if (txtNumber.Text != "") // search by 학번

            {

                sql = "SELECT * FROM Student WHERE StudentID='" + txtNumber.Text.ToString() + "'";

            }


            conn = new OleDbConnection(connstr);

            conn.Open();

            cmd = new OleDbCommand(sql, conn);


            reader = cmd.ExecuteReader();

            lbStudent.Items.Clear();


            while (reader.Read())

            {

                string item = "";

                item += reader["ID"].ToString() + " ";

                item += reader["StudentID"].ToString() + " ";

                item += reader["NAME"].ToString() + " ";

                item += reader["PHONE"].ToString();

                lbStudent.Items.Add(item);

            }

            reader.Close();

            conn.Close();

            conn = null;

        }


이제 다 끝났군요. Access DB를 사용한 삽입, 삭제, 수정, 검색 작업은 이렇게 하면 되겠습니다. 아, 마지막으로 끝낼 때는 connection을 닫았는지 확인하고 끝냅니다.

        private void Button_Click_1(object sender, RoutedEventArgs e)

        {

            if (conn != null)

                conn.Close();

            Close();

        }


Beeeye Dmu