Difference Between Observablecollection and Bindinglist

Difference between ObservableCollection and BindingList

An ObservableCollection can be updated from UI exactly like any collection. The true difference is rather straightforward:

ObservableCollection<T> implements INotifyCollectionChanged which provides notification when the collection is changed (you guessed ^^)
It allows the binding engine to update the UI when the ObservableCollection is updated.

However, BindingList<T> implements IBindingList.

IBindingList provides notification on collection changes, but not only that. It provides a whole bunch of functionality which can be used by the UI to provide a lot more things than only UI updates according to changes, like:

  • Sorting
  • Searching
  • Add through factory (AddNew member function).
  • Readonly list (CanEdit property)

All these functionalities are not available in ObservableCollection<T>

Another difference is that BindingList relays item change notifications when its items implement INotifyPropertyChanged. If an item raises a PropertyChanged event, the BindingList will receive it an raises a ListChangedEvent with ListChangedType.ItemChanged and OldIndex=NewIndex (if an item was replaced, OldIndex=-1). ObservableCollection doesn't relay item notifications.

Note that in Silverlight, BindingList is not available as an option: You can however use ObservableCollections and ICollectionView (and IPagedCollectionView if I remember well).

Why NOT BindingList in WPF

This may be of interest:

http://www.themissingdocs.net/wordpress/?p=465

most important paragraphs:

But the implementation does not scale, it is slow, it performs terribly with larger lists. If your element type supports INotifyPropertyChanged, every time one of those elements raises the property changed event the entire list is walked to work out the index in the list of the item which raised the event! I was in shock when I first realised this. You see BindingList is truly just a rather thin wrapper over Collection, so there is no metadata associated with each entry, all of the binding of the element PropertyChanged event is directed to a single handler, and all it gets given is the source and the name of the changed property, so there is no way to include the NewIndex parameter in ListChangedEventArgs without doing a search. (By default this search even uses the default object comparator, so if you happen to have two different but sometimes equal objects in your list, enjoy the results…)

Another side note – AddNew, the other feature which BindingList has which Collection does not – also does not scale. It has to use IndexOf to find out where in the list the newly added item ended up in case it needs to cancel the add, because it supports auto sorting in derived types. (BindingList does not support auto sorting itself…)

ObservableCollection(Of T) vs BindingList(Of T)?

Claber,

I would keep the BindingList, because BindingList supports more interfaces and more feature rich than ObservableCollection.
For example:

  1. BindingList implements IList of T, whereas ObservableCollection does not.
  2. BindingList implements ICancelAddNew interface that data binding mechanisms uses for cancelling the newly added item (when you clicked escape after adding a row to DataGridView, the row will dissappear).

I'm very new to WPF myself, and don't know the specific advantages ObservableCollection offers.

Hope this helps.

WPF ObservableCollection T vs BindingList T

The IBindingList interface and BindingList class are defined in the System.ComponentModel namespace, and so are not strictly Windows Forms related.

Have you checked if xamGrid supports binding to a ICollectionView source? If so, you could expose your data sources using this interface and back it using a BindingListCollectionView.

You could also create a subclass of ObservableCollection<T> and implement the IBindingList interface:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;

public class ObservableBindingList<T> : ObservableCollection<T>, IBindingList
{
// Constructors
public ObservableBindingList() : base()
{
}

public ObservableBindingList(IEnumerable<T> collection) : base(collection)
{
}

public ObservableBindingList(List<T> list) : base(list)
{
}

// IBindingList Implementation
public void AddIndex(PropertyDescriptor property)
{
throw new NotImplementedException();
}

public object AddNew()
{
throw new NotImplementedException();
}

public bool AllowEdit
{
get { throw new NotImplementedException(); }
}

public bool AllowNew
{
get { throw new NotImplementedException(); }
}

public bool AllowRemove
{
get { throw new NotImplementedException(); }
}

public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
{
throw new NotImplementedException();
}

public int Find(PropertyDescriptor property, object key)
{
throw new NotImplementedException();
}

public bool IsSorted
{
get { throw new NotImplementedException(); }
}

public event ListChangedEventHandler ListChanged;

public void RemoveIndex(PropertyDescriptor property)
{
throw new NotImplementedException();
}

public void RemoveSort()
{
throw new NotImplementedException();
}

public ListSortDirection SortDirection
{
get { throw new NotImplementedException(); }
}

public PropertyDescriptor SortProperty
{
get { throw new NotImplementedException(); }
}

public bool SupportsChangeNotification
{
get { throw new NotImplementedException(); }
}

public bool SupportsSearching
{
get { throw new NotImplementedException(); }
}

public bool SupportsSorting
{
get { throw new NotImplementedException(); }
}
}

Alternately, you could subclass BindingList<T> and implement the INotifyCollectionChanged interface.

WPF, ObservableCollection/BindingList binding to ListView

Items in your collection should be of type that implements INotifyPropertyChanged interface. This way your listview will be notified that property value in your single item object has changed. ObservableCollection rises CollectionChanged event only when collection changes (items added, removed, etc.)

Quote from the MSDN library article on ObservableCollection

To fully support transferring data
values from binding source objects to
binding targets, each object in your
collection that supports bindable
properties must implement an
appropriate property changed
notification mechanism such as the
INotifyPropertyChanged interface.

And yeah in case you want to attach handlers to your child elements property chnaged event look at the answer for this question how to do it, although the question is bit different but the answer i think will served your purpose -
Observable Collection Property Changed on Item in the Collection

what is the difference between TwoWay databinding and ObservableCollection?

The two "things" TwoWay databinding and ObservableCollection are different things which can collaborate, but are not directly linked. Databinding is a concept and ObservableCollection is an implementation of an interface (INotifyCollectionChanged) which is used in the implementation of the concept of databinding in the .NET framework. In itself, INotifyCollectionChanged is a small part of this implementation.

In fact you can use TwoWay databinding without ObservableCollections and ObservableCollections without databinding.

Databinding is a mecanism allowing you to bind a business object property (Often a ViewModel property) to an UI property. OneWay Databinding provides support for update of UI when the object is changed (which requires implementation of INotifyPropertyChanged and/or INotifyCollectionChanged on the business object). TwoWay Databinding provides twoway support as its name suggest it: Object => UI (like OneWay do) AND UI => Object. UI to Object updates does not requires implementation of INotifyCollectionChanged nor INotifyPropertyChanged.

Observable collection now is interesting because it implements INotifyCollectionChanged, which makes it a good candidate to create databindable collections. But I use often INotifyCollectionChanged without databinding, and I am pretty sure you can find other collections which implement INotifyCollectionChanged (like PagedCollectionView)

Does it answer your question?

Custom ObservableCollection T or BindingList T with support for periodic notifications

We are talking about two things here:

  1. The changes to the collection. This raises the event INotifyCollectionChanged.CollectionChanged
  2. The changes to the properties of the items. This raises the event INotifyPropertyChanged.PropertyChanged

The interface INotifyCollectionChanged needs to be implemented by your custom collection. The interface INotifyPropertyChanged needs to be implemented by your items. Furthermore, the PropertyChanged event only tells you which property was changed on an item but not what was the previous value.

This means, your items need to have a implementation that goes something like this:

  • Have a timer that runs every N seconds
  • Create a HashSet<string> that contains the names of all properties that have been changed. Because it is a set, each property can only be contained one or zero times.
  • When a property is changed, add its name to the hash set if it is not already in it.
  • When the timer elapses, raise the PropertyChanged event for all properties in the hash set and clear it afterwards.

Your collection would have a similar implementation. It is however a little bit harder, because you need to account for items that have been added and deleted between to timer events. This means, when an item is added, you would add it to a hash set "addedItems". If an item is removed, you add it to a "removedItems" hash set, if it is not already in "addedItems". If it is already in "addedItems", remove it from there. I think you get the picture.

To adhere to the principle of separation of concerns and single responsibility, it would be even better to have your items implement INotifyPropertyChanged in the default way and create a wrapper that does the consolidation of the events. That has the advantage that your items are not cluttered with code that doesn't belong there and this wrapper can be made generic and used for every class that implements INotifyPropertyChanged.

The same goes for the collection: You can create a generic wrapper for all collections that implement INotifyCollectionChanged and let the wrapper do the consolidation of the events.

Should I use an Observable or a BindingList for exposing changing data that I want to put into a UI

On the ViewModel you want to expose your data as state. So ViewModels that implement INotifyPropertyChanged or expose readonly properties that themselves expose INPC (INotifyPropertyChanged) is good. In this case the VM (ViewModel) would have an Orders property

BindingList<MyOrder> Orders { get; }

Then the VM I would think would subscribe to an Observable Sequence of change notifications. This sounds like your SignalR channel provides you this already. In previous projects we conflated Add/Insert and Update into a single "upsert" message, and then had Remove/Delete and Clear/Reset messages too.

The difficulty you will get by trying to manage state locally is the "State of the World" problem. If you try to get the current snapshot first, then subscribe to live values, you can miss a value while reading the snapshot. If however, you subscribe first then get the snapshot, you may receive a value twice. In this case you will also have to deal with queuing the live data until you have processed the snapshot.

With this in mind, you can either try to move everything to a single threaded and predictable sequence model, or just get something else that does this for you (Akavache?). If you do think it is worth doing yourself, then it is probably worth trying a model that uses checkpoints/sequenceIds, so the client can just resubscribe from a known point. This will allow the service to either give them just the recent changes, or a full snapshot if their checkpoint is suffciently stale.

So, yeah expose it as an

IObservable<ChangeNotification<MyOrder>> OrderChanges { get;}

Where ChangeNotification conveys either an Upsert (with new items), Deletion (with ids/keys to delete) or Reset.
You wont use a subject anywhere if it is done properly ;-)

What is the difference between ObservableCollection and INotifyPropertyChanged?

ObservableCollection is a specialized collection that can notify subscribers when its contents change, while INotifyPropertyChanged is an interface that allows implementors to notify subscribers when one of their properties changes value.

You are probably wondering how the two are related (because both are "involved" in the setter in your example).

Consider this code:

var model = new MyViewModel(); // assume it's the class with Payments inside
model.Payments.Add(new PaymentViewModel());

Subscribers to the INotifyCollectionChanged.CollectionChanged event would now know that things have changed and they should update accordingly.

But now look at this:

var model = new MyViewModel(); // assume it's the class with Payments inside
model.Payments.Add(new PaymentViewModel()); // OK, we know what this does

model.Payments = new ObservableCollection<PaymentViewModel>();

After adding an item to the collection we then swap the entire collection for another one. If an ItemsControl is bound to this collection we expect it to update itself and reflect the fact that model.Payments ends up being empty. But how can it do that?

CollectionChanged will not help because the original collection (after receiving its first item) was not modified; we just discarded it and installed another in its place. The only one who knows that the switch happened is the Payments property setter. So the setter utilizes INotifyPropertyChanged to tell subscribers that the collection has been replaced with another, and they should of course update their status.

Conclusion: Data binding works automagically in WPF because all the databound controls listen to the INotifyPropertyChanged of their DataContext, and if the binding target implements INotifyCollectionChanged they subscribe to that as well. If the binding target changes they are notified through INotifyPropertyChanged, unsubscribe from INotifyCollectionChanged on the old target and subscribe to it on the new one.

ObservableCollection vs. List

Interesting question, considering that both List and ObservableCollection implement IList<T> there isn't much of a difference there, ObservableCollection also implements INotifyCollectionChanged interface, which allows WPF to bind to it.

One of the main differences is that ObservableCollection does not have AddRange method, which might have some implications.

Also, I would not use ObservableCollection for places where I know I would not be binding to, for this reason, it is important to go over your design and make sure that you are taking the correct approach in separating layers of concern.

As far as the differences between Collection<T> and List<T> you can have a look here
Generic Lists vs Collection



Related Topics



Leave a reply



Submit