WPF ComboBox와
MSSQL 연동 완벽 가이드
이 포스트에서는 WPF ComboBox를 활용해 로컬 MSSQL 데이터베이스와 연동하는 방법을 다룹니다. XAML과 C# 소스 코드를 제공하며, C# 코드에는 상세 주석을 추가했습니다. 데이터 로드, 추가, 수정 기능과 ObservableCollection 사용법을 초보자도 이해할 수 있도록 설명합니다.
주요 키워드: WPF, ComboBox, MSSQL, 데이터 바인딩, ObservableCollection, C#, XAML, Windows 인증
1. 준비 단계: MSSQL 설정
WPF에서 MSSQL 데이터를 사용하려면 데이터베이스를 준비해야 합니다. 로컬 MSSQL에 People
테이블을 생성합니다.
테이블 생성 SQL
CREATE DATABASE TestDB;
USE TestDB;
CREATE TABLE People (
Id INT PRIMARY KEY IDENTITY(1,1),
Name NVARCHAR(100) NOT NULL
);
INSERT INTO People (Name) VALUES ('John Doe'), ('Jane Smith'), ('Bob Johnson');
설명: TestDB
데이터베이스를 만들고, Id
(자동 증가 기본 키)와 Name
(최대 100자 문자열) 열을 정의합니다. 초기 데이터를 삽입해 테스트를 준비합니다.
- Server:
localhost
- 로컬 MSSQL 서버. - 인증:
Trusted_Connection=True
로 Windows 계정 사용.
참고: MSSQL이 설치되어 있지 않다면 SQL Server Express를 설치하세요.
2. WPF ComboBox 샘플 소스
WPF ComboBox를 통해 MSSQL 데이터를 표시하고, 추가 및 수정 기능을 구현합니다. XAML과 C# 코드를 모두 제공합니다.
XAML 코드 (MainWindow.xaml)
<Window x:Class="WpfComboBoxSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF ComboBox with MSSQL" Height="400" Width="500">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="이름 선택:" FontWeight="Bold" Margin="0,0,0,5"/>
<ComboBox x:Name="dataBoundComboBox" Grid.Row="1" Width="200" HorizontalAlignment="Left"
DisplayMemberPath="Name" SelectedValuePath="Id"
SelectionChanged="DataBoundComboBox_SelectionChanged" Margin="0,0,0,10"/>
<TextBlock Grid.Row="2" Text="선택된 항목:" FontWeight="Bold" Margin="0,0,0,5"/>
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,0,0,10">
<TextBox x:Name="editNameTextBox" Width="150" Margin="0,0,10,0"/>
<Button Content="수정" Width="60" Click="UpdateButton_Click"/>
</StackPanel>
<StackPanel Grid.Row="4" Orientation="Horizontal">
<TextBox x:Name="newNameTextBox" Width="150" Margin="0,0,10,0"/>
<Button Content="추가" Width="60" Click="AddButton_Click"/>
</StackPanel>
</Grid>
</Window>
설명: ComboBox
로 데이터 선택 UI를 구성하고, TextBox
와 버튼으로 추가/수정 인터페이스를 제공합니다. DisplayMemberPath
는 표시할 속성, SelectedValuePath
는 값으로 사용할 속성을 지정합니다.
C# 코드 (MainWindow.xaml.cs) - 상세 주석 포함
using System; // 기본 클래스와 예외 처리 사용
using System.Collections.ObjectModel; // ObservableCollection 클래스 사용
using System.Data.SqlClient; // MSSQL 데이터베이스 연결
using System.Windows; // WPF 창 및 기본 기능
using System.Windows.Controls; // UI 컨트롤(ComboBox, Button 등)
namespace WpfComboBoxSample
{
public partial class MainWindow : Window
{
// MSSQL 연결 문자열: 로컬 서버 접속, TestDB 사용, Windows 인증
private readonly string connectionString = "Server=localhost;Database=TestDB;Trusted_Connection=True;";
// ObservableCollection: 동적 데이터 바인딩을 위한 Person 객체 리스트
private ObservableCollection<Person> people;
// 생성자: UI 초기화 및 데이터 로드
public MainWindow()
{
InitializeComponent(); // XAML에서 정의된 UI 요소 초기화
people = new ObservableCollection<Person>(); // 동적 컬렉션 객체 생성
dataBoundComboBox.ItemsSource = people; // ComboBox에 데이터 소스 연결
LoadData(); // 프로그램 시작 시 MSSQL 데이터 로드
}
// MSSQL에서 데이터를 읽어오는 메서드
private void LoadData()
{
people.Clear(); // 기존 데이터 제거
try
{
using (SqlConnection conn = new SqlConnection(connectionString)) // DB 연결 객체 생성 및 자동 해제
{
conn.Open(); // 데이터베이스 연결 열기
string query = "SELECT Id, Name FROM People"; // People 테이블에서 데이터 조회 쿼리
using (SqlCommand cmd = new SqlCommand(query, conn)) // 쿼리 실행 명령 객체
{
using (SqlDataReader reader = cmd.ExecuteReader()) // 쿼리 결과 읽기
{
while (reader.Read()) // 결과 행을 하나씩 순회
{
// Person 객체 생성 후 ObservableCollection에 추가
people.Add(new Person
{
Id = reader.GetInt32(0), // Id 열 읽기 (정수형)
Name = reader.GetString(1) // Name 열 읽기 (문자열)
});
}
}
}
}
// 데이터가 있으면 첫 번째 항목 선택, 없으면 선택 해제
dataBoundComboBox.SelectedIndex = people.Count > 0 ? 0 : -1;
}
catch (Exception ex) // 연결 실패, 쿼리 오류 등 예외 처리
{
MessageBox.Show($"데이터 로드 실패: {ex.Message}"); // 사용자에게 오류 메시지 표시
}
}
// ComboBox 선택 변경 이벤트: 선택된 항목을 TextBox에 표시
private void DataBoundComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (dataBoundComboBox.SelectedItem is Person selectedPerson) // 선택된 항목이 Person 객체인지 확인
editNameTextBox.Text = selectedPerson.Name; // 선택된 이름 TextBox에 표시
else
editNameTextBox.Text = string.Empty; // 선택 해제 시 TextBox 비우기
}
// "추가" 버튼 클릭 이벤트: 새 항목을 MSSQL에 삽입
private void AddButton_Click(object sender, RoutedEventArgs e)
{
string newName = newNameTextBox.Text.Trim(); // 입력된 이름 (공백 제거)
if (string.IsNullOrEmpty(newName)) // 입력값이 비어 있는지 확인
{
MessageBox.Show("이름을 입력하세요.");
return; // 비어 있으면 메서드 종료
}
try
{
using (SqlConnection conn = new SqlConnection(connectionString)) // DB 연결
{
conn.Open(); // 데이터베이스 연결 열기
// 새 항목 삽입 후 생성된 ID 반환 쿼리
string query = "INSERT INTO People (Name) VALUES (@Name); SELECT SCOPE_IDENTITY();";
using (SqlCommand cmd = new SqlCommand(query, conn)) // 쿼리 실행 명령
{
cmd.Parameters.AddWithValue("@Name", newName); // 쿼리 파라미터로 이름 추가
int newId = Convert.ToInt32(cmd.ExecuteScalar()); // 삽입된 ID 반환
people.Add(new Person { Id = newId, Name = newName }); // UI에 새 항목 추가
}
}
newNameTextBox.Text = string.Empty; // 입력란 초기화
MessageBox.Show("항목이 추가되었습니다."); // 성공 메시지 표시
}
catch (Exception ex) // 삽입 실패 시 예외 처리
{
MessageBox.Show($"추가 실패: {ex.Message}"); // 오류 메시지 표시
}
}
// "수정" 버튼 클릭 이벤트: 선택된 항목을 MSSQL에서 업데이트
private void UpdateButton_Click(object sender, RoutedEventArgs e)
{
if (dataBoundComboBox.SelectedItem is Person selectedPerson) // 선택된 항목 확인
{
string updatedName = editNameTextBox.Text.Trim(); // 수정된 이름 (공백 제거)
if (string.IsNullOrEmpty(updatedName)) // 입력값이 비어 있는지 확인
{
MessageBox.Show("수정할 이름을 입력하세요.");
return; // 비어 있으면 메서드 종료
}
try
{
using (SqlConnection conn = new SqlConnection(connectionString)) // DB 연결
{
conn.Open(); // 데이터베이스 연결 열기
string query = "UPDATE People SET Name = @Name WHERE Id = @Id"; // 업데이트 쿼리
using (SqlCommand cmd = new SqlCommand(query, conn)) // 쿼리 실행 명령
{
cmd.Parameters.AddWithValue("@Name", updatedName); // 새 이름 파라미터
cmd.Parameters.AddWithValue("@Id", selectedPerson.Id); // 조건 ID 파라미터
cmd.ExecuteNonQuery(); // 쿼리 실행 (업데이트)
}
}
selectedPerson.Name = updatedName; // UI 객체 속성 업데이트
dataBoundComboBox.Items.Refresh(); // ComboBox UI 새로고침
MessageBox.Show("항목이 수정되었습니다."); // 성공 메시지 표시
}
catch (Exception ex) // 수정 실패 시 예외 처리
{
MessageBox.Show($"수정 실패: {ex.Message}"); // 오류 메시지 표시
}
}
else
{
MessageBox.Show("수정할 항목을 선택하세요."); // 선택된 항목 없음 경고
}
}
}
// Person 클래스: MSSQL 데이터와 매핑되는 데이터 모델
public class Person
{
public int Id { get; set; } // 고유 식별자 (MSSQL의 Id 열과 매핑)
public string Name { get; set; } // 사람 이름 (MSSQL의 Name 열과 매핑)
}
}
설명: XAML
은 UI를 정의하고, C#
는 MSSQL과의 데이터 처리를 담당합니다. 주석은 각 줄의 역할과 동작을 명확히 설명합니다.
3. ObservableCollection이란?
ObservableCollection은 WPF에서 동적 데이터 바인딩에 사용되는 컬렉션 클래스입니다. List
와 달리 INotifyCollectionChanged
를 구현해 컬렉션 변경 시 UI를 자동 갱신합니다.
- 주요 특징: 항목 추가/삭제 시 UI 실시간 반영.
- 사용 목적:
ComboBox.ItemsSource
에 연결해 데이터 동기화. - 샘플 동작:
people.Add()
로 새 항목 추가 시ComboBox
에 즉시 표시. - 제한점: 속성 변경(예:
Name
)은 반영되지 않음.INotifyPropertyChanged
필요.
코드 분석: ObservableCollection
을 사용해 MSSQL 데이터를 채우고, UI를 동적으로 업데이트합니다.
4. 결론
이 가이드에서는 WPF ComboBox와 MSSQL 연동을 다뤘습니다. XAML로 UI를 구성하고, 상세 주석이 포함된 C# 코드로 데이터를 처리했습니다. ObservableCollection으로 동적 데이터 관리를 배웠습니다.
'WPF' 카테고리의 다른 글
WPF MVVM으로 공학용 계산기 만들기: 초보자 가이드 (40) | 2025.03.11 |
---|---|
WPF 커스텀 텍스트 박스와 원형 버튼 구현하기 (14) | 2025.03.10 |
WPF DataGrid 샘플 소스 (6) | 2025.03.07 |
WPF로 간단한 계산기 만들기 (4) | 2025.03.07 |
WPF DataGrid에 데이터 바인딩하기 (7) | 2025.03.06 |