본문 바로가기

프로그래밍 언어 노트/C#

[C#/WPF] ObservableCollection, List 간의 변환

WPF 에서 ListBox, ListView등에 List<T> 을 ItemSource 로 사용하거나 바인딩 하여 사용하는 경우가 많다.

그러나 일반적인 List<T> 의 경우 변경된 List의 내용을 UI 에서 실시간으로 반영하지 않는다.

코드비하인드인경우는 이벤트콜백, MVVM 과 같은경우는 ICommand 등으로 실행되는것이 아니면 바로 반영되지 않고 Invoke 나 BackgroundWalker를 사용하거나 뭐 그래야하는데..

Obserable Colletion의 경우 옵저버 패턴이 적용되어 바뀌면 알아서 UI 에 반영된다.

 

ObservableCollection 클래스

 

ObservableCollection 클래스 (System.Collections.ObjectModel)

항목이 추가 또는 제거되거나 전체 목록이 새로 고쳐진 경우 알림을 제공하는 동적 데이터 컬렉션을 나타냅니다.Represents a dynamic data collection that provides notifications when items get added, removed, or when th

docs.microsoft.com

 

RX의 조상님쯤.. 되시겠다.

 

사용법

사용법을 간단히 살펴보자면

디자이너 XML

디자이너에서 위와같이 ListBox를 2개 만들고

public partial class MainWindow : Window
{
    public List<string> listExample { get; set; }
    public ObservableCollection<string> observableExample { get; set; }
    public MainWindow()
    {
        InitializeComponent();

        listExample = new List<string>();
        observableExample = new ObservableCollection<string>();

        listBoxForList.ItemsSource = listExample;
        listBoxForObservable.ItemsSource = observableExample;


        DispatcherTimer timer = new DispatcherTimer();   


        timer.Interval = TimeSpan.FromSeconds(1);    

        timer.Tick += new EventHandler(timer_Tick);          

        timer.Start();                  

    }

    private void timer_Tick(object sender, EventArgs e)
    {
        listExample.Add("Test");
        observableExample.Add("Test");
    }
}

코드 비하인드에서 위와 같이 설정한다.

하나의 리스트박스에는 List<string> 을 나머지 하나는 ObservableCollection을 ItemSource 로 설정한다.

Timer가 1초에 한번씩 List, ObservableCollection에 "Test"라는 키워드를 넣는다.

 

앞서 설명한듯이 ObservableCollection을 사용한 ListBox에서만 정상적으로 갱신된다.

 

List <-> Observable Collection

ObservableCollection -> List는 뚝딱이다. LINQ 에있는 ToList() 를 사용하면된다.

List -> ObservableCollection은 변환 함수가 없기때문에 직접 넣어주어야한다. 역시 LINQ 를 사용하면 쉽다.

observableExample.ToList(); //O -> L
listExample.ForEach(x => observableExample.Add(x)); //L -> O
728x90