반응형
해당 포스팅은 개인적으로 C# WPF를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서
일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.

 

 

C#WPF에서 MVVM패턴으로 
프로그래밍 할때 ObservableCollection의
개념과 역할에 대해
알아보자.

 

반응형
내용 요약

 

ObservableCollection은 WPF에서 데이터 바인딩을 활용하는 데 매우 중요한 클래스이다. 이 클래스는 컬렉션의 변경 사항을 View(UI)에 자동으로 반영하도록 설계되었다. System.Collections.ObjectModel 네임스페이스에 포함되어 있으며, 컬렉션에 요소를 추가하거나 제거할 때 이를 알리는 기능을 제공한다.

 

목차
1.ObservableCollection이란 무엇인가?
2.ObservableCollection의 주요 특징
3.일반 컬렉션과의 차이점
4.ObservableCollection의 사용 사례
5.ObservableCollection의 구현 예제
   - 기본 사용법
   - 데이터 바인딩과의 통합
   - 컬렉션 변경 알림 처리
   - 필터링 및 정렬 적용
6.ObservableCollection과 INotifyCollectionChanged
7.ObservableCollection 사용 시 주의점
8.ObservableCollection의 확장과 활용

 

 

1.ObservableCollection이란 무엇인가?

 

ObservableCollection<T>는 컬렉션이 변경될 때(예: 요소 추가, 제거, 전체 초기화) 변경 알림을 발생시켜 UI와 데이터의 동기화를 유지하도록 돕는 클래스이다. WPF의 데이터 바인딩 시 컬렉션 변경 사항이 자동으로 UI에 반영되도록 하기 위해 주로 사용된다

namespace System.Collections.ObjectModel
{
    public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
    {
        // 생성자 및 메서드 정의
    }
}

 

2.ObservableCollection의 주요 특징

 

  1. 자동 UI 업데이트
    컬렉션의 데이터가 변경되면 변경 사항이 UI에 자동으로 반영된다.
  2. INotifyCollectionChanged 인터페이스 구현
    컬렉션의 변경 사항(추가, 삭제, 갱신)을 알리기 위해 CollectionChanged 이벤트를 제공한다.
  3. INotifyPropertyChanged 인터페이스 구현
    컬렉션의 속성 변경 사항을 알리기 위해 PropertyChanged 이벤트를 제공한다.
  4. 다양한 컬렉션 작업 지원
    기본적인 추가(Add), 제거(Remove), 삽입(Insert), 정리(Clear) 작업을 제공한다.

 

3.일반 컬렉션과의 차이점

4.ObservableCollection의 사용 사례

 

  1. 데이터 바인딩
    UI에서 실시간으로 변경 사항을 반영해야 할 때 유용하다.
  2. 동적 목록
    사용자 인터페이스에서 동적으로 항목을 추가하거나 제거할 때 사용된다.
  3. MVVM 패턴에서 컬렉션 관리
    ViewModel에서 데이터를 관리할 때 주요한 역할을 한다.
5.ObservableCollection의 구현 예제

 

기본 사용법

ObservableCollection은 컬렉션에 데이터를 추가하거나 제거하는 데 매우 직관적이다.

using System.Collections.ObjectModel;

public class MainViewModel
{
    public ObservableCollection<string> Names { get; set; }

    public MainViewModel()
    {
        Names = new ObservableCollection<string>
        {
            "Alice",
            "Bob",
            "Charlie"
        };
    }

    public void AddName(string name)
    {
        Names.Add(name);
    }

    public void RemoveName(string name)
    {
        Names.Remove(name);
    }
}

 

데이터 바인딩과의 통합

ObservableCollection은 데이터 바인딩을 활용할 때 매우 강력하다.

 

<XAML 코드>

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ObservableCollection Demo" Height="300" Width="400">
    <Grid>
        <StackPanel>
            <ListBox ItemsSource="{Binding Names}" />
            <TextBox x:Name="NameInput" Width="200" Margin="10" />
            <Button Content="Add Name" Command="{Binding AddNameCommand}" CommandParameter="{Binding Text, ElementName=NameInput}" />
        </StackPanel>
    </Grid>
</Window>

 

<ViewModel 코드>

using System.Collections.ObjectModel;
using System.Windows.Input;

public class MainViewModel
{
    public ObservableCollection<string> Names { get; set; }
    public ICommand AddNameCommand { get; }

    public MainViewModel()
    {
        Names = new ObservableCollection<string> { "Alice", "Bob", "Charlie" };

        AddNameCommand = new RelayCommand(AddName);
    }

    private void AddName(object parameter)
    {
        if (parameter is string name && !string.IsNullOrWhiteSpace(name))
        {
            Names.Add(name);
        }
    }
}

 

컬렉션 변경 알림 처리

컬렉션 변경 시 이벤트를 수신하여 추가 작업을 수행할 수도 있다.

Names.CollectionChanged += (s, e) =>
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            Console.WriteLine("Item added");
            break;
        case NotifyCollectionChangedAction.Remove:
            Console.WriteLine("Item removed");
            break;
    }
};

 

필터링 및 정렬 적용

WPF에서는 기본적으로 ObservableCollection에 필터링과 정렬 기능이 없다. 이를 구현하려면 CollectionView를 사용해야 한다.

using System.ComponentModel;
using System.Windows.Data;

public ICollectionView FilteredNames { get; set; }

public MainViewModel()
{
    Names = new ObservableCollection<string> { "Alice", "Bob", "Charlie" };
    FilteredNames = CollectionViewSource.GetDefaultView(Names);

    FilteredNames.Filter = item => item.ToString().StartsWith("A");
}

 

6.ObservableCollection과 INotifyCollectionChanged

 

ObservableCollection은 INotifyCollectionChanged 인터페이스를 구현하여 컬렉션 변경 사항을 알린다.

public interface INotifyCollectionChanged
{
    event NotifyCollectionChangedEventHandler CollectionChanged;
}

이 이벤트는 Add, Remove, Replace 등의 작업에 반응하며, 변경 내용을 전달한다.

 

7.ObservableCollection 사용 시 주의점

 

스레드 안전성
ObservableCollection은 UI 스레드에서만 안전하게 사용할 수 있다. 백그라운드 스레드에서 작업하려면 Dispatcher를 사용해야 한다.

Application.Current.Dispatcher.Invoke(() => Names.Add("New Name"));

 

 

성능
많은 데이터 변경이 있을 경우 성능 문제가 발생할 수 있다. 이 경우 CollectionChanged 이벤트를 비활성화하거나 List<T>로 작업 후 한 번에 업데이트하는 방법을 고려할 수 있다.

 

필터링 및 정렬
기본적으로 필터링과 정렬을 지원하지 않으므로, CollectionView를 사용하는 것이 필요하다.

 

 

8.ObservableCollection의 확장과 활용

 

ObservableCollection을 상속받아 고유한 동작을 추가할 수 있다

public class CustomObservableCollection<T> : ObservableCollection<T>
{
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        Console.WriteLine($"{item} added at index {index}");
    }

    protected override void RemoveItem(int index)
    {
        Console.WriteLine($"{this[index]} removed from index {index}");
        base.RemoveItem(index);
    }
}

 


결론 및 개인적인 생각

 

ObservableCollection은 WPF MVVM 패턴에서 필수적인 도구로, 데이터와 UI를 동기화하는 데 강력한 기능을 제공한다. 특히, 실시간 업데이트와 바인딩을 결합하여 사용자 경험을 크게 향상시킬 수 있다.

 

개인적으로, WPF 프로젝트를 처음 시작할 때 List<T>로 바인딩 문제를 겪은 후 ObservableCollection을 알게 되었고, 이를 통해 데이터 변경 사항이 즉시 UI에 반영되는 과정을 경험하며 큰 만족감을 느꼈다. 그러나 성능 최적화와 스레드 안전성 같은 추가적인 요소도 항상 염두에 두어야 한다고 생각하며, WPF를 배우는 모든 개발자가 반드시 익혀야 할 개념 중 하나라고 확신한다.

반응형

+ Recent posts