본문 바로가기

C# WPF

[C# WPF] Combo Box와 ListBox를 이용한 DB 프로그램(학생정보관리프로그램)

ComboBox와 ListBox를 이용하면 다양한 표현을 할 수 있습니다.

이번에 같이 살펴볼 프로그램은 학생정보관리프로그램입니다. 학생DB는 Access를 사용했습니다. DB의 이름은 '재학생.accdb', 테이블은 '의료IT공학과'이며, 다음과 같이 구성되어 있습니다.

 

왼쪽 그림은 VisualStudio에서 서버탐색기로 연결한 그림이고, 오른쪽 그림은 Access에서 본 그림입니다.

프로그램의 실행모습입니다. 위쪽에 TextBox가 있고 여기에 이름이나 학번을 입력하면 DB에서 그 학생의 정보를 학생정보 창의 각 TextBox들에 표시합니다.

오른쪽의 지도교수별 ComboBox를 배치했습니다. 지도교수를 선택하면 그 지도학생들이 오른쪽 아래의 ListBox에 표시됩니다.

 

이에 대한 Xaml 파일은 다음과 같습니다.

<Window x:Class="MIT_S.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="의료IT공학과 재학생(2014.5)" Height="380" Width="525">
    <Grid Background="#FFCFDBEC">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="35" />
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Line Stroke="White" Grid.Row="0" Grid.ColumnSpan="2" VerticalAlignment="Bottom" Stretch="Fill" X2="525" ></Line>
        <Line Stroke="White" Grid.Column="0" Grid.RowSpan="2" HorizontalAlignment="Right" Stretch="Fill" Y2="380" ></Line>
        <StackPanel Orientation="Horizontal" Margin="5">
            <TextBlock Margin="5,0,10,0" VerticalAlignment="Center">학생정보검색(이름이나 학번 입력) : </TextBlock>
            <TextBox Margin="0,0,10,0" Name="txtStudent" Width="100" KeyDown="txtStudent_KeyDown"></TextBox>
            <Button Name="btnSearch" Width="70" Height="25" VerticalAlignment="Top" Click="btnSearch_Click">검색</Button>
        </StackPanel>
        <ComboBox Name="cbProf" Grid.Column="1" Margin="5" SelectionChanged="cbProf_SelectionChanged"> 지도교수별 </ComboBox>
        <StackPanel Grid.Row="1" Margin="20,10,10,10" >
            <TextBlock Height="24" HorizontalAlignment="Center" >학생정보</TextBlock>
            <StackPanel Orientation="Horizontal" Height="24" >
                <TextBlock Width="80" VerticalAlignment="Center">학과: </TextBlock>
                <TextBox Name="txt학과" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">학번:</TextBlock>
                <TextBox Name="txt학번" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">성명:</TextBlock>
                <TextBox Name="txt성명" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">학년:</TextBlock>
                <TextBox Name="txt학년" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">성별:</TextBlock>
                <TextBox Name="txt성별" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">집전화:</TextBlock>
                <TextBox Name="txt집전화" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">핸드폰:</TextBlock>
                <TextBox Name="txt핸드폰" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">부모연락처:</TextBlock>
                <TextBox Name="txt부모연락처" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">우편번호:</TextBlock>
                <TextBox Name="txt우편번호" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">주소:</TextBlock>
                <TextBox Name="txt주소" Width="300" Height="22" VerticalContentAlignment ="Top"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBlock Height="24" Width="80" VerticalAlignment="Center">지도교수:</TextBlock>
                <TextBox Name="txt지도교수" Width="100" Height="22" VerticalAlignment="Center"></TextBox>
            </StackPanel>
        </StackPanel>
        <ListBox Name="lbStudent" Margin="5,5,5,10" Grid.Column="1" Grid.Row="1" SelectionChanged="lbStudent_SelectionChanged"></ListBox>

    </Grid>
</Window>

ComboBox 부분과 ListBox 부분을 살펴보겠습니다. 위의 Xaml 파일에 색칠된 부분을 참조하세요. 둘다 SelectionChanged 이벤트를 연결하였습니다.

코드는 다음과 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Data.OleDb;

namespace MIT_S
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        string connStr = null;
        OleDbConnection conn = null;
        OleDbCommand cmd = null;
        OleDbDataReader reader = null;

        public MainWindow()
        {
            InitializeComponent();
            makeCombo();
            DBConnect();
        }

        private void DBConnect()
        {
            connStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=./재학생.accdb; Persist Security Info=False";
        }

        private void makeCombo()
        {
            string[] prof = { "장원O", "김병O", "강병O", "정제O", "김필O", "김진O", "허용O", "조용O", "김웅O" };

            foreach(string p in prof)
                cbProf.Items.Add(p);

            cbProf.SelectedIndex = 0;
        }

        // 참고(WPF ComboBox): http://www.dotnetperls.com/combobox-wpf
        // 지도교수를 선택하면 DB를 열고 선택된 지도교수의 학생 리스트를 ListBox에 표시
        private void cbProf_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbProf.SelectedIndex == 0)
                return;

            var comboBox = sender as ComboBox;
            string profName = comboBox.SelectedItem as string;

            string sql = string.Format("SELECT * FROM 의료IT공학과 WHERE 지도교수 = '{0}'", profName);
            conn = new OleDbConnection(connStr);

            try
            {
                conn.Open();
                cmd = new OleDbCommand(sql, conn);

                reader = cmd.ExecuteReader();
                lbStudent.Items.Clear();

                while (reader.Read())
                {
                    // 학번 = 앞 두글자만 선택
                    lbStudent.Items.Add((reader["학번"].ToString()).Substring(0, 2) + " " + reader["성명"].ToString());
                }

                reader.Close();
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void lbStudent_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox lb = sender as ListBox;

            string sql = string.Format("SELECT * FROM 의료IT공학과 WHERE 성명 = '{0}'", (lb.SelectedItem.ToString()).Substring(3));
            conn = new OleDbConnection(connStr);

            try
            {
                conn.Open();
                cmd = new OleDbCommand(sql, conn);

                reader = cmd.ExecuteReader();
               
                while (reader.Read())
                {
                    txt학과.Text = reader["학과"].ToString();
                    txt학번.Text = reader["학번"].ToString();
                    txt성명.Text = reader["성명"].ToString();
                    txt학년.Text = reader["학년"].ToString();
                    txt성별.Text = reader["성별"].ToString();
                    txt집전화.Text = reader["집전화"].ToString();
                    txt핸드폰.Text = reader["핸드폰"].ToString();
                    txt부모연락처.Text = reader["부모연락처"].ToString();
                    txt우편번호.Text = reader["우편번호"].ToString();
                    txt주소.Text = reader["주소"].ToString();
                    txt지도교수.Text = reader["지도교수"].ToString();
                }

                reader.Close();
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            string sql = null;
            if (txtStudent.Text == "")
            {
                MessageBox.Show("학번이나 이름을 입력해주세요", "Search Warning!!");
                return;
            }

            // 지도교수별 학생목록 ListBox를 Clear하고, '지도교수별'이라고 표시
            lbStudent.Items.Clear();
            cbProf.SelectedIndex = 0;

            clearTextBoxes();
            sql = string.Format("SELECT * FROM 의료IT공학과 WHERE 성명 = '{0}' OR 학번 = '{0}'", txtStudent.Text);

            conn = new OleDbConnection(connStr);

            try
            {
                conn.Open();
                cmd = new OleDbCommand(sql, conn);

                reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    txt학과.Text = reader["학과"].ToString();
                    txt학번.Text = reader["학번"].ToString();
                    txt성명.Text = reader["성명"].ToString();
                    txt학년.Text = reader["학년"].ToString();
                    txt성별.Text = reader["성별"].ToString();
                    txt집전화.Text = reader["집전화"].ToString();
                    txt핸드폰.Text = reader["핸드폰"].ToString();
                    txt부모연락처.Text = reader["부모연락처"].ToString();
                    txt우편번호.Text = reader["우편번호"].ToString();
                    txt주소.Text = reader["주소"].ToString();
                    txt지도교수.Text = reader["지도교수"].ToString();
                }

                reader.Close();
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void clearTextBoxes()
        {
            txt학과.Text = "";
            txt학번.Text = "";
            txt성명.Text = "";
            txt학년.Text = "";
            txt성별.Text = "";
            txt집전화.Text = "";
            txt핸드폰.Text = "";
            txt부모연락처.Text = "";
            txt우편번호.Text = "";
            txt주소.Text = "";
            txt지도교수.Text = "";
        }

        private void txtStudent_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Enter)
                return;
            TextBox box = sender as TextBox;
            if (string.IsNullOrEmpty(box.Text))
                return;
            btnSearch_Click(sender, e);
        }
    }
}

실행화면 몇 커트를 보여드립니다.

 

ComboBox를 누르면 지도교수 이름이 나옵니다. 여기에서 이름을 선택하면 cbProf_SelectionChanged 이벤트 함수가 실행됩니다. 이때 SelectedIndex 가 0이면 "지도교수별"이라고 표시됩니다. 따라서 SelectedIndex가 0이 아니면 지도교수 이름이 선택된 것이고, DB에서 선택된 지도교수인 학생들을 찾아서 ListBox에 표시합니다. 학번은 년도만 표시하기 위해 앞의 두 글자만 Substring 메소드로 추출합니다.

 

위의 그림은 강병익이 지도교수인 모든 학생을 ListBox에 표시한 상태입니다. 이제 여기에서 학생 이름을 선택하면 그 학생의 정보가 왼쪽의 TextBox에 표시됩니다.

학생의 이름과 정보의 일부분은 개인정보보호를 위해 가렸습니다. 

왼쪽 위의 TextBox에 이름이나 학번으로 직접 학생을 검색할 수 있습니다.

"민다O" 학생의 이름이나 학번으로 검색하면 학생정보가 나타나고, 이때 오른쪽 ListBox와 ComboBox는 초기화시켜 줍니다. 즉 ComboBox의 SelectedIndex = 0 으로 해주고, ListBox의 Item을 Clear 해줍니다.

유용한 프로그램이 하나 만들어졌죠?

 

BeeEye Dmu