Diferença entre ObservableCollection e BindingList

236

Quero saber a diferença entre ObservableCollectione BindingListporque usei ambos para notificar sobre qualquer alteração de adição / exclusão na Origem, mas na verdade não sei quando preferir uma sobre a outra.

Por que eu escolheria um dos seguintes sobre o outro?

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();

ou

BindingList<Employee> lstEmp = new BindingList<Employee>();
Azhar
fonte

Respostas:

278

Um ObservableCollectionpode ser atualizado da interface do usuário exatamente como qualquer coleção. A verdadeira diferença é bastante direta:

ObservableCollection<T>implementa INotifyCollectionChangedque fornece notificação quando a coleção é alterada (você adivinhou ^^) Permite que o mecanismo de ligação atualize a interface do usuário quando ela ObservableCollectioné atualizada.

No entanto, BindingList<T>implementa IBindingList.

IBindingListfornece notificação sobre alterações na coleção, mas não apenas isso. Ele fornece várias funcionalidades que podem ser usadas pela interface do usuário para fornecer muito mais coisas do que apenas atualizações da interface do usuário de acordo com as alterações, como:

  • Ordenação
  • Procurando
  • Adicionar pela fábrica (função de membro AddNew).
  • Lista somente leitura (propriedade CanEdit)

Todas essas funcionalidades não estão disponíveis no ObservableCollection<T>

Outra diferença é que BindingListretransmite as notificações de alteração de itens quando seus itens são implementados INotifyPropertyChanged. Se um item gerar um PropertyChangedevento, BindingListele receberá um aumento ListChangedEventcom ListChangedType.ItemChangede e OldIndex=NewIndex(se um item foi substituído OldIndex=-1). ObservableCollectionnão retransmite as notificações do item.

Note que no Silverlight, BindingListnão está disponível como uma opção: No entanto, você pode usar ObservableCollections e ICollectionView(e IPagedCollectionViewse me lembro bem).

Eilistraee
fonte
5
Outra coisa a considerar é o desempenho, consulte: themissingdocs.net/wordpress/?p=465
Jarek Mazur
Obrigado, eu não estava ciente da implementação real do BindingList. Eu tenho a tendência de usar ObservableCollection e ICollectionView
Eilistraee
5
Enquanto as informações nesta resposta estiverem corretas, qualquer usuário do WPF deve tomar cuidado: BindingList não implementa INotifyCollectionChanged e causará um vazamento de memória se vinculado à propriedade ItemsSource de um controle. O ObservableCollection implementa a interface e não causa vazamentos.
Brandon capa
1
Se o BindingList implementa a classificação, por que você não pode classificar uma grade vinculada a um BindingList?
31719 Robert Harvey
É BindingListobsoleto?
Shimmy Weitzhandler 27/10/19
27

A diferença prática é que BindingList é para WinForms e ObservableCollection é para WPF.

De uma perspectiva do WPF, o BindingList não é suportado adequadamente e você nunca o utilizaria em um projeto WPF, a menos que fosse realmente necessário.

Dean Chalk
fonte
1
Interessante. Como desenvolvedor do Silverlight, eu não sabia disso. Obrigado. E se você deseja classificar e filtrar, as implementações do ICollectionView são suas ^ ^ #
Eilistraee
27
Por que é "Não suportado"? O ViewManager (interno) está dentro do assembly PresentationFramework e é compatível com ele. Ligue-o a um ItemsControl, por exemplo, e as notificações de alterações serão respeitadas (ou seja, os itens serão adicionados e removidos). Se fosse específico para WinForms, não deveria ser melhor colocado no namespace Forms?
David Kiff
7
Concordado com David, ele está no espaço para nome System.Collections, por isso deve ser totalmente suportado pelo WPF. O WPF é apenas uma maneira diferente de layout da interface do usuário.
23712 Justin justin
13
Concordo com David também, eu uso BindingList frequentemente no WPF porque o ObservableCollection não enviará notificações de alteração de propriedade de seus itens.
Amnésia
3
Para dar um exemplo de "not supportet": Acabei de encontrar um vazamento de memória no meu aplicativo WPF causado por algumas BindingLists que não implementam INotifyCollectionChanged
Breeze
4

As diferenças mais importantes, como recursos e notificações de alterações sobre os elementos contidos, já são mencionadas na resposta aceita, mas há outras que também merecem destaque:

atuação

Quando AddNewé chamado, BindingList<T>procura o item adicionado por uma IndexOfpesquisa. E se Timplementa INotifyPropertyChangedo índice de um elemento alterado também é pesquisado por IndexOf(embora não haja nova pesquisa desde que o mesmo item seja alterado repetidamente). Se você armazenar milhares de elementos na coleção, será preferível ObservableCollection<T>(ou uma IBindingListimplementação customizada com custo de pesquisa O (1)).

Completude

  • A IBindingListinterface é enorme (talvez não seja o design mais limpo) e permite que os implementadores implementem apenas um subconjunto de seus recursos. Por exemplo, as AllowNew, SupportsSortinge SupportsSearchingpropriedades de dizer se AddNew, ApplySorte Findmétodos podem ser utilizados, respectivamente. Muitas vezes, surpreende as pessoas que BindingList<T>não suportam a classificação. Na verdade, ele fornece alguns métodos virtuais, permitindo que as classes derivadas adicionem os recursos ausentes. A DataViewclasse é um exemplo para uma IBindingListimplementação completa ; no entanto, não é para coleções digitadas em primeiro lugar. E a BindingSourceclasse no WinForms é um exemplo híbrido: suporta classificação se envolver outra IBindingListimplementação, que suporta classificação.

  • ObservableCollection<T>já é uma implementação completa da INotifyCollectionChangedinterface (que possui apenas um único evento). Ele também possui membros virtuais, mas ObservableCollection<T>normalmente é derivado pelo mesmo motivo que sua Collection<T>classe base : para personalizar adicionar / remover itens (por exemplo, em uma coleção de modelos de dados) em vez de ajustar os recursos de ligação.

Cópia x quebra automática

Ambos ObservableCollection<T>e BindingList<T>têm um construtor, que aceita uma lista já existente. Embora eles se comportem de maneira diferente quando são instanciados por outra coleção:

  • BindingList<T>atua como um invólucro observável para a lista fornecida e as alterações executadas no BindingList<T>serão refletidas na coleção subjacente.
  • ObservableCollection<T>por outro lado, passa uma nova List<T>instância para o Collection<T>construtor base e copia os elementos da coleção original para essa nova lista. Obviamente, se Tfor um tipo de referência, as alterações nos elementos serão visíveis na coleção original, mas a coleção em si não será atualizada.
György Kőszeg
fonte
1

Mais uma grande diferença entre ObservableCollectione BindingListisso é útil e pode ser um fator de decisão de lance no tópico:

BindingList Manipulador de alterações de lista:

Alteração da lista BindingList

ObservableCollection Alteração de coleção:

Coleção ObervableCollection alterada

Resumo do acima: Se uma propriedade de um item for alterada BindingList, o ListChangedevento fornecerá detalhes completos da propriedade (no PropertyDescriptor) e ObservableCollectionnão fornecerá isso. De fato ObservableCollection, não gerará evento de alteração para uma propriedade alterada em um item.

As conclusões acima são INotifyPropertyChangedimplementadas em classes de modelo. Por padrão, nenhum gera o evento alterado se uma propriedade for alterada em um item.

Kylo Ren
fonte
Eu acho que isso (PropertyDescriptor) pode ser uma fonte de um vazamento de memória
Abdulkarim Kanaan