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

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



답변

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
        }
    }
}


답변

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

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

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


답변

부터 프로의 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. 루이비통 핸드백 ($ 5000)
  2. 클라이브 크리스천의 황제 폐하 향수 ($ 215,000)
  3. 구찌 선글라스 ($ 2000)

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

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

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

ObservableCollection-변경시 알림

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

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

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


답변

가장 큰 용도 중 하나는 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);
}


답변

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

주로 WPF에서 사용

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


답변

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();
}