Qual é a utilização do ObservableCollection no .net?


227

Qual é a utilização do ObservableCollection no .net?


1
@ alpha-mouse: Você pode fornecer um pouco mais de informação sobre o problema que está tentando resolver? Isso ajudará as pessoas a dar exemplos relevantes.
Jazza

@Jazza: Acabei de etiquetas da questão mudou =) I't de santosh questão
alfa-rato

3
@TheMuffinMan é verdade, mas prefiro a maneira como as coisas são explicadas no stackoverflow em comparação com a maneira muito rígida e formal do MSDN de explicar suas próprias criações.
Sizons

Respostas:


224

ObservableCollection é uma coleção que permite que o código fora da coleção esteja ciente de quando ocorrem alterações na coleção (adicionar, mover, remover). É muito usado no WPF e no Silverlight, mas seu uso não se limita a isso. O código pode adicionar manipuladores de eventos para ver quando a coleção foi alterada e reagir através do manipulador de eventos para fazer algum processamento adicional. Isso pode estar alterando uma interface do usuário ou executando alguma outra operação.

O código abaixo realmente não faz nada, mas demonstra como você anexaria um manipulador em uma classe e, em seguida, usaria os argumentos do evento para reagir de alguma forma às alterações. O WPF já possui muitas operações, como atualizar a interface do usuário, para que você as obtenha gratuitamente ao usar o 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.OldsItemspode ser nulo dependendo da ação. Pode jogar NullReferenceException.
dovid

7
sidenote: quando a ação é movimento, o elemento movido aparecerá em ambos os newitems e OldItems
bohdan_trotsenko

Obrigado por este:> WPF já tem muitas operações como atualizar a UI construído em que você obtê-los gratuitamente ao usar ObservableCollections
SlowLearner

157

Um ObservableCollectionfunciona essencialmente como uma coleção regular, exceto que implementa as interfaces:

Como tal, é muito útil quando você deseja saber quando a coleção foi alterada. Um evento é acionado que informa ao usuário quais entradas foram adicionadas / removidas ou movidas.

Mais importante, eles são muito úteis ao usar a ligação de dados em um formulário.


54

Do Pro C # 5.0 e do .NET 4.5 Framework

A ObservableCollection<T>classe é muito útil, pois tem a capacidade de informar objetos externos quando seu conteúdo foi alterado de alguma forma (como você pode imaginar, trabalhar com ele ReadOnlyObservableCollection<T>é muito semelhante, mas é de natureza somente leitura). De muitas maneiras, trabalhar com o ObservableCollection<T>é idêntico ao trabalho List<T>, já que essas duas classes implementam as mesmas interfaces principais. O que torna a ObservableCollection<T>classe exclusiva é que essa classe suporta um evento chamado CollectionChanged. Este evento será acionado sempre que um novo item for inserido, um item atual for removido (ou realocado) ou se toda a coleção for modificada. Como qualquer evento, CollectionChanged é definido em termos de um delegado, que neste caso é NotifyCollectionChangedEventHandler. Esse delegado pode chamar qualquer método que use um objeto como o primeiro parâmetro e umNotifyCollectionChangedEventArgscomo o segundo. Considere o seguinte método Main (), que preenche uma coleção observável contendo objetos Person e organiza o CollectionChangedevento:

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

O NotifyCollectionChangedEventArgsparâmetro de entrada define duas propriedades importantes, OldItemse NewItems, que fornecerá uma lista dos itens que estavam atualmente na coleção antes do lançamento do evento e os novos itens envolvidos na alteração. No entanto, você desejará examinar essas listas apenas nas circunstâncias corretas. Lembre-se de que o evento CollectionChanged pode disparar quando itens são adicionados, removidos, realocados ou redefinidos. Para descobrir qual dessas ações acionou o evento, você pode usar a propriedade Action de NotifyCollectionChangedEventArgs. A propriedade Action pode ser testada em relação a qualquer um dos seguintes membros da NotifyCollectionChangedActionenumeração:

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

Membros de System.Collections.ObjectModel


1
será o evento de fogo people_CollectionChanged se eu mudar o nome de uma pessoa na na coleção (sem alterar a própria coleção?)
BKSpurgeon

25

Explicação sem Código

Para aqueles que querem uma resposta sem nenhum código por trás (boom-tish), jogarei minha mão para cima:

Coleções normais - sem notificações

De vez em quando eu vou para Nova York e minha esposa me pede para comprar coisas. Então eu levo uma lista de compras comigo. A lista tem muitas coisas lá, como:

  1. Bolsa Louis Vuitton (US $ 5000)
  2. Perfume Imperial Majesty de Clive Christian (US $ 215.000)
  3. Óculos de Sol Gucci ($ 2000)

hahaha bem, eu não estou comprando essas coisas. Então eu as cruzo e as removo da lista e adiciono:

  1. 12 dúzias de bolas de golfe Titleist.
  2. Bola de boliche de 12 libras.

Então, geralmente chego em casa sem as mercadorias e ela nunca fica satisfeita. O fato é que ela não sabe sobre o que eu tiro da lista e o que eu adiciono nela; ela não recebe notificações.

ObservableCollection - notifica quando as alterações são feitas

Agora, sempre que eu removo algo da lista: ela recebe uma notificação em seu telefone (por exemplo, sms / email etc)!

A coleção observável funciona da mesma maneira. Se você adicionar ou remover algo de ou para ele: alguém é notificado. E quando são notificados, eles ligam para você e você fica atento. Obviamente, as consequências são personalizáveis ​​por meio do manipulador de eventos.

Isso resume tudo!


7

Um dos maiores usos é que você pode vincular componentes da interface do usuário a um e eles responderão adequadamente se o conteúdo da coleção for alterado. Por exemplo, se você vincular a ItemsSource de um ListView a um, o conteúdo do ListView será atualizado automaticamente se você modificar a coleção.

EDIT: Aqui está um código de exemplo do MSDN: http://msdn.microsoft.com/en-us/library/ms748365.aspx

Em C #, conectar o ListBox à coleção pode ser tão fácil quanto

listBox.ItemsSource = NameListData;

embora, se você não conectou a lista como um recurso estático e definiu NameItemTemplate, pode substituir o ToString () de PersonName. Por exemplo:

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

6

é uma coleção usada para notificar principalmente a interface do usuário para alterar a coleção, suporta a notificação automática.

Usado principalmente no WPF,

Onde digamos, suponha que você tenha uma interface do usuário com uma caixa de listagem e um botão adicionar e quando você clicar no botão ele, um objeto do tipo suponha que a pessoa será adicionada à coleção obseravabl e vincular essa coleção ao ItemSource da caixa de listagem, assim que você adicionar um novo item da coleção, o Listbox será atualizado automaticamente e incluirá mais um item.


realmente isso acontece? : O
Reis

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

você pode explicar por que FooObservableCollection implementou a coleção? E por que você substituiu o InsertItem?
Arie #

@ Arie: honestamente, 8 anos depois, não me lembro, então não faço ideia. Pelo que vejo nos documentos, não há necessidade disso, tudo deve sair da caixa.
Abatishchev
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.