Often, the object you want to use as the source is a collection of multiple custom objects, each of which represents a data object that serves as the source for one instance of a repeated binding. For instance, you might have a CustomerOrders collection consisting of CustomerOrder objects, where your application iterates over the collection to determine how many orders exist and the data contained in each.
You can enumerate over any collection that implements the IEnumerable interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. This interface exposes an event that must be raised whenever the underlying collection changes.
WPF provides the ObservableCollection<(Of <(T>)>) class, which is a built-in implementation of a data collection that exposes the INotifyCollectionChanged interface. The individual data objects within the collection must satisfy the requirements described in the preceding sections. For an example, see How to: Create and Bind to an ObservableCollection. Before implementing your own collection, consider using ObservableCollection<(Of <(T>)>) or one of the existing collection classes, such as List<(Of <(T>)>), Collection<(Of <(T>)>), and BindingList<(Of <(T>)>), among many others.
WPF never binds directly to a collection. If you specify a collection as a data source, WPF actually binds to the collection's default view. For information about default views see Data Binding Overview.
If you have an advanced scenario and want to implement your own collection, consider using IList, which provides a non-generic collection of objects that can be individually accessed by index and thus the best performance.