In WPF/Silverlight, binding UI objects such as DataGrid or ListBox to collections is typically done using an ObservableCollection instead of the generic List object. This way, our UI is automatically synchronized since the observable collection provides event notification to WPF data binding engine whenever items are added, removed, or when the whole list is refreshed. The LINQ extension methods that return a collection actually return IEnumerable<T>. The .NET framework for Silverlight provides built-in extension methods to convert IEnumerable<T> to List<T> and Array<T> but there’s no method available to convert the collection to ObservableCollection<T>(WPF developers can simply use this constructor overload) . So here’s one you may find useful:
public static class CollectionExtensions
{
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerableList)
{
if (enumerableList != null)
{
//create an emtpy observable collection object
var observableCollection = new ObservableCollection<T>();
//loop through all the records and add to observable collection object
foreach (var item in enumerableList)
observableCollection.Add(item);
//return the populated observable collection
return observableCollection;
}
return null;
}
}
Extension methods are very powerful and I am planning to post an example demonstrating their potential.
March 19, 2009 at 8:39 PM
Do you have any follow up examples of this? I’ve been trying to get something like this to work for a few days and I’m not having much luck.
thanks!
March 20, 2009 at 1:45 AM
The ObservableCollection actually has a constructor that takes an IEnumerable. It would be better to use the constructor because every call to Add(item) causes the CollectionChanged event to fire, which means more overhead.
March 21, 2009 at 11:21 AM
@Chris
I followed this post with an introduction to creating and using Extension Methods here. Hope that helps in clarifying concepts.
@Jann
Unfortunately, that constructor is only available for WPF programmers (msdn link here ) and there’s no such facility for Silverlight developers (msdn link here). I should have explicitly said this in my post; will do it soon. Thanks for pointing out.
July 23, 2009 at 2:17 PM
I have an error on “foreach (var item in enumerableList)”:
“Only a single enumeration is supported by this IEnumerable.”
Can’t figure out, what’s the problem
??
July 23, 2009 at 2:18 PM
I’m using it in Silverlight App (3.0)
July 27, 2009 at 4:27 PM
@haveaproblem
Haven’t ran into it anytime. Can you share the code how you are using it?
August 5, 2009 at 9:04 AM
if I load related entities using .Expand(“”) in the query then I get “Only a single enumeration is supported by this IEnumerable” error.
var qry =
from p in TheContext.Products.Expand(“Supplier”).Expand(“Category”)
orderby p.ProductName
select p;
The below line throws exception:
List products = productQuery.EndExecute(result).ToList();
August 5, 2009 at 9:22 AM
In the above code, I had foreach (var item in enumerableList) code before using the .ToList() fn., after removing the foreach code, .ToList() works fine. Also, I noticed that you can only enumerate foreach (var item in enumerableList) once, if you repeat foreach(…) code one more time, you get this error. So, it is a best to convert it to List and use it.
August 5, 2009 at 4:16 PM
@Raj
I also found this thread in Silverlight forums. Looks like ADO.NET data services aren’t happy with enumerables in Silverlight 3 RTM.
December 16, 2009 at 8:33 PM
I’ve posted a VB.NET version of the code on my blog here, http://www.fredmastro.com/post/Sending-GenericList-collection-back-to-WCF-ObservableCollection.aspx
I posted a copy of the article and referenced this page as the source. If you wish me to remove the article, let me know. Thank you.
June 9, 2010 at 7:59 PM
[...] Source: http://smehrozalam.wordpress.com/2009/01/18/ienumerabletoobservablecollection/ [...]
July 9, 2010 at 2:09 AM
Awesome – thanks for sharing – I am on SL4 and using LINQ on an XML file and then binding to it – perfect!
October 13, 2010 at 1:28 AM
Is there any way to use ria .. load data into an observable collection, and then have that observable collection accessed by multiple datagrids on different pages or child windows throughout a solution?
July 14, 2011 at 10:04 PM
public static class CollectionExtensions { public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerableList) { if (enumerableList != null) { //create an observable collection object //you can pass the IEnumerable inside the ObservableCollection Constructor return new ObservableCollection<T>(enumerableList); } return null; } }August 14, 2011 at 7:03 AM
This is the version that i have been using, works good… The add new item, delete & edit buttons were grayed out on my dataform and i spent hours trying to figure out what the problem was. I used the pagedcollectionview and the buttons were visible. v2_Customer is name of my table. The event below fires when the datagrid_selection_changed event fires.
Dim taskList As ObservableCollection(Of v2_Customer) = New ObservableCollection(Of v2_Customer)
‘ Dim custID As Guid = (CType(V2_CustomerDataGrid.SelectedItem, _
‘ v2_Customer)).Cust_UUID
‘ Generate some task data and add it to the task list.
For index = 1 To 14
taskList.Add(New v2_Customer() With _
{.Cust_UUID = custID, .Company_UUID, .City
})
Next
Dim taskListView As New PagedCollectionView(taskList)
Me.CustomerDataForm1.ItemsSource = taskListView