.net에서 ObservableCollection을 사용하는 것은 무엇입니까?


227

.net에서 ObservableCollection을 사용하는 것은 무엇입니까?


1
@ alpha-mouse : 해결하려는 문제에 대해 좀 더 자세한 정보를 줄 수 있습니까? 사람들이 관련 예제를 제공하는 데 도움이됩니다.
재즈

@Jazza : 방금 질문의 태그를 변경했습니다 =) santosh의 질문이 아닙니다
alpha-mouse

3
@TheMuffinMan은 사실이지만 MSDN의 자체 제작 방법을 설명하기에는 너무 엄격하지 않고 스택 오버플로에 대해 설명하는 방법을 선호합니다.
Sizons

답변:


224

ObservableCollection은 컬렉션에 대한 변경 (추가, 이동, 제거)이 발생할 때 컬렉션 외부의 코드를 인식 할 수있는 컬렉션입니다. WPF 및 Silverlight에서 많이 사용되지만 그 용도는 여기에만 국한되지 않습니다. 코드는 이벤트 처리기를 추가하여 컬렉션이 변경된시기를 확인한 다음 이벤트 처리기를 통해 추가 처리를 수행 할 수 있습니다. UI를 변경하거나 다른 작업을 수행 중일 수 있습니다.

아래 코드는 실제로 아무것도하지 않지만 클래스에 핸들러를 첨부 한 다음 이벤트 인수를 사용하여 변경 사항에 어떤 방식으로 반응하는지 보여줍니다. WPF에는 이미 UI 새로 고침과 같은 많은 작업이 있으므로 ObservableCollections를 사용할 때 무료로 사용할 수 있습니다.

class Handler
{
    private ObservableCollection<string> collection;

    public Handler()
    {
        collection = new ObservableCollection<string>();
        collection.CollectionChanged += HandleChange;
    }

    private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        foreach (var x in e.NewItems)
        {
            // do something
        }

        foreach (var y in e.OldItems)
        {
            //do something
        }
        if (e.Action == NotifyCollectionChangedAction.Move)
        {
            //do something
        }
    }
}

21
e.NewItems& e.OldsItems는 조치에 따라 널일 수 있습니다. 던질 수 있습니다 NullReferenceException.
dovid

7
sidenote : Action이 Move 일 때 이동 한 요소는 NewItems와 OldItems 모두에 나타납니다.
bohdan_trotsenko

감사합니다 :> WPF에는 이미 UI 새로 고침과 같은 많은 작업이있어 ​​ObservableCollections를 사용할 때 무료로 사용할 수 있습니다.
SlowLearner

157

ObservableCollection이 인터페이스를 구현하는 것을 제외하고는 보통 징수와 같은 본질적으로 작동합니다 :

따라서 컬렉션이 언제 변경되었는지 알고 싶을 때 매우 유용합니다. 어떤 항목이 추가 / 제거 또는 이동되었는지 알려주는 이벤트가 트리거됩니다.

더 중요한 것은 폼에서 데이터 바인딩을 사용할 때 매우 유용합니다.


54

부터 프로의 C # 5.0과 .NET 4.5 프레임 워크

ObservableCollection<T>클래스는 내용이 어떤 식 으로든 변경되었을 때 외부 객체에 정보를 제공 할 수 있다는 점에서 매우 유용합니다 (추상과 같이 작업하는 ReadOnlyObservableCollection<T>것은 매우 유사하지만 읽기 전용). 이 두 클래스가 모두 동일한 코어 인터페이스를 구현한다는 점 에서 여러 가지면에서와 함께 작업하는 ObservableCollection<T>것은 작업과 동일합니다 List<T>. ObservableCollection<T>클래스를 고유 하게 만드는 것은이 클래스가라는 이벤트를 지원한다는 것 CollectionChanged입니다. 이 이벤트는 새 항목을 삽입하거나 현재 항목을 제거 (또는 재배치)하거나 전체 컬렉션이 수정 될 때마다 발생합니다. 다른 이벤트와 마찬가지로 CollectionChanged는 대리자 측면에서 정의되며이 경우에는입니다 NotifyCollectionChangedEventHandler. 이 대리자는 개체를 첫 번째 매개 변수로 사용하는 모든 메서드와NotifyCollectionChangedEventArgs두 번째로. Person 오브젝트를 포함하는 관찰 가능 콜렉션을 채우고 CollectionChanged이벤트를 연결하는 다음 Main () 메소드를 고려하십시오 .

class Program
{
   static void Main(string[] args)
   {
     // Make a collection to observe and add a few Person objects.
     ObservableCollection<Person> people = new ObservableCollection<Person>()
     {
        new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
        new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
     };
     // Wire up the CollectionChanged event.
     people.CollectionChanged += people_CollectionChanged;
     // Now add a new item.
     people.Add(new Person("Fred", "Smith", 32));

     // Remove an item.
     people.RemoveAt(0);

     Console.ReadLine();
   }
   static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   {
       // What was the action that caused the event?
        Console.WriteLine("Action for this event: {0}", e.Action);

        // They removed something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            Console.WriteLine("Here are the OLD items:");
            foreach (Person p in e.OldItems)
            {
                Console.WriteLine(p.ToString());
            }
            Console.WriteLine();
        }

        // They added something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            // Now show the NEW items that were inserted.
            Console.WriteLine("Here are the NEW items:");
            foreach (Person p in e.NewItems)
            {
                Console.WriteLine(p.ToString());
            }
        }
   }
}

들어오는 NotifyCollectionChangedEventArgs매개 변수는 두 가지 중요한 속성 OldItems및을 정의합니다.이 속성 NewItems은 이벤트가 발생하기 전에 현재 컬렉션에 있던 항목 목록과 변경에 관련된 새 항목을 제공합니다. 그러나 올바른 환경에서만이 목록을 검사하려고합니다. 항목이 추가, 제거, 재배치 또는 재설정 될 때 CollectionChanged 이벤트가 발생할 수 있습니다. 이러한 조치 중 이벤트를 트리거 한 조치를 발견하기 위해 NotifyCollectionChangedEventArgs의 조치 특성을 사용할 수 있습니다. Action 속성은 다음 NotifyCollectionChangedAction열거 형 멤버 중 하나에 대해 테스트 할 수 있습니다 .

public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}

System.Collections.ObjectModel 멤버


1
컬렉션에있는 사람의 이름을 변경하면 (컬렉션 자체를 변경하지 않고) people_CollectionChanged 이벤트가 발생합니까?
BKSpurgeon

25

코드없는 설명

뒤에 코드가없는 답변을 원하는 사람들을 위해 (붐-티쉬) 내 손을 내밀어 보겠습니다.

일반 컬렉션-알림 없음

가끔 뉴욕에 가서 아내가 물건을 사달라고 부탁합니다. 그래서 나는 쇼핑 목록을 가져갑니다. 목록에는 다음과 같은 많은 것들이 있습니다.

  1. 루이비통 핸드백 ($ 5000)
  2. 클라이브 크리스천의 황제 폐하 향수 ($ 215,000)
  3. 구찌 선글라스 ($ 2000)

하하 잘 나는 그 물건을 사지 않는다. 그래서 나는 그것들을 건너서 목록에서 제거하고 대신에 추가한다.

  1. 12 개의 타이틀리스트 골프 공.
  2. 12 파운드 볼링 공.

그래서 나는 보통 물건없이 집에 돌아와서 그녀는 결코 기뻐하지 않습니다. 문제는 그녀가 내가 목록에서 무엇을 빼고 무엇을 추가하는지 알지 못한다는 것입니다. 그녀는 알림을받지 않습니다.

ObservableCollection-변경시 알림

이제 목록에서 무언가를 제거 할 때마다 : 그녀는 휴대 전화 (예 : SMS / 이메일 등)로 알림을받습니다!

관찰 가능한 컬렉션은 동일한 방식으로 작동합니다. 무언가를 추가하거나 제거하면 누군가에게 통지됩니다. 그리고 그들이 통보되면, 그들은 당신을 호출하고 당신은 귀가 가득합니다. 물론 이벤트 핸들러를 통해 결과를 사용자 정의 할 수 있습니다.

그것은 모든 것을 요약합니다!


7

가장 큰 용도 중 하나는 UI 구성 요소를 하나에 바인딩 할 수 있으며 컬렉션의 내용이 변경되면 적절하게 응답하는 것입니다. 예를 들어 ListView의 ItemsSource를 하나로 바인딩하면 컬렉션을 수정하면 ListView의 내용이 자동으로 업데이트됩니다.

편집 : MSDN의 샘플 코드는 다음과 같습니다. http://msdn.microsoft.com/en-us/library/ms748365.aspx

C #에서는 ListBox를 컬렉션에 연결하는 것이 쉬울 수 있습니다.

listBox.ItemsSource = NameListData;

목록을 정적 리소스로 정의하지 않고 NameItemTemplate을 정의하지 않은 경우 PersonName의 ToString ()을 재정의 할 수 있습니다. 예를 들면 다음과 같습니다.

public override ToString()
{
    return string.Format("{0} {1}", this.FirstName, this.LastName);
}

6

주로 UI에서 컬렉션 변경을 알리는 데 사용되는 컬렉션이며 자동 알림을 지원합니다.

주로 WPF에서 사용

어디에서 목록 상자와 추가 버튼이있는 UI가 있고 버튼을 클릭하면 person 유형의 객체가 obseravablecollection에 추가 되고이 컬렉션을 Listbox의 ItemSource에 바인딩한다고 가정합니다. 컬렉션의 새 항목 인 Listbox는 자체적으로 업데이트되고 항목을 하나 더 추가합니다.


정말 이런 일이 ?? : O
Kings

5
class FooObservableCollection : ObservableCollection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        base.Add(index, Foo);

        if (this.CollectionChanged != null)
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
    }
}

var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;

collection.Add(new Foo());

void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
    Foo newItem = e.NewItems.OfType<Foo>().First();
}

FooObservableCollection이 컬렉션을 구현 한 이유를 설명 할 수 있습니까? 왜 InsertItem ovverided 되었습니까?
Arie

@Arie : 솔직히, 8 년 후 기억이 나지 않아요. 내가 문서에서 볼 수 있듯이 이것 중 어느 것도 필요하지 않습니다. 모두 상자에서 나옵니다.
abatishchev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.