Convert List<T> to ObservableCollection<T> in WP7

C#.NetWindows Phone-7Collections

C# Problem Overview


I don't know if it's just too late or what, but I don't see how to do this...

What I'm expecting to do, and what the object browser says is there, is this:

var oc = new ObservableCollection<T>( new List<T>() );

But ObservableCollection<T> has a single parameterless constructor. The object browser says there is 2 overloads where List and IEnuerable should be able to be passed in.

Is there something wrong with my setup? Are the constructors not on the phone version? (that would be strange)

If this really doesn't exist, what is the standard way of doing this with WP7 now?

C# Solutions


Solution 1 - C#

ObservableCollection has several constructors which have input parameter of List<T> or IEnumerable<T>:
List<T> list = new List<T>();
ObservableCollection<T> collection = new ObservableCollection<T>(list);

Solution 2 - C#

Apparently, your project is targeting Windows Phone 7.0. Unfortunately the constructors that accept IEnumerable<T> or List<T> are not available in WP 7.0, only the parameterless constructor. The other constructors are available in Silverlight 4 and above and WP 7.1 and above, just not in WP 7.0.

I guess your only option is to take your list and add the items into a new instance of an ObservableCollection individually as there are no readily available methods to add them in bulk. Though that's not to stop you from putting this into an extension or static method yourself.

var list = new List<SomeType> { /* ... */ };
var oc = new ObservableCollection<SomeType>();
foreach (var item in list)
    oc.Add(item);

But don't do this if you don't have to, if you're targeting framework that provides the overloads, then use them.

Solution 3 - C#

To convert List<T> list to observable collection you may use following code:

var oc = new ObservableCollection<T>();
list.ForEach(x => oc.Add(x));

Solution 4 - C#

You'll have to write your own extension method to do this:

	public static class CollectionEx
	{
	  /// <summary>
	  /// Copies the contents of an IEnumerable list to an ObservableCollection
	  /// </summary>
	  /// <typeparam name="T">The type of objects in the source list</typeparam>
	  /// <param name="enumerableList">The source list to be converted</param>
	  /// <returns>An ObservableCollection containing the objects from the source list</returns>
	  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;
	  }
	}

Solution 5 - C#

Extension method from this answer https://stackoverflow.com/questions/731626/ilistt-to-observablecollectiont works pretty well

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerable) {
  var col = new ObservableCollection<T>();
  foreach ( var cur in enumerable ) {
    col.Add(cur);
  }
  return col;
}

Solution 6 - C#

ObservableCollection<FacebookUser_WallFeed> result = new ObservableCollection<FacebookUser_WallFeed>(FacebookHelper.facebookWallFeeds);
          

Solution 7 - C#

Use this:

List<Class1> myList;
ObservableCollection<Class1> myOC = new ObservableCollection<Class1>(myList);

Solution 8 - C#

If you are going to be adding lots of items, consider deriving your own class from ObservableCollection and adding items to the protected Items member - this won't raise events in observers. When you are done you can raise the appropriate events:

public class BulkUpdateObservableCollection<T> : ObservableCollection<T>
{
    public void AddRange(IEnumerable<T> collection)
    {
        foreach (var i in collection) Items.Add(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        OnPropertyChanged(new PropertyChangedEventArgs("Count"));
    }
 }

When adding many items to an ObservableCollection that is already bound to a UI element (such as LongListSelector) this can make a massive performance difference.

Prior to adding the items, you could also ensure you have enough space, so that the list isn't continually being expanded by implementing this method in the BulkObservableCollection class and calling it prior to calling AddRange:

    public void IncreaseCapacity(int increment)
    {
        var itemsList = (List<T>)Items;
        var total = itemsList.Count + increment;
        if (itemsList.Capacity < total)
        {
            itemsList.Capacity = total;
        }
    }

Solution 9 - C#

I made an extension so now I can just load a collection with a list by doing:

MyObservableCollection.Load(MyList);

The extension is:

public static class ObservableCollectionExtension
{
  public static ObservableCollection<T> Load<T>(this ObservableCollection<T> Collection, List<T> Source)
  {
          Collection.Clear();    
          Source.ForEach(x => Collection.Add(x));    
          return Collection;
   }
}

Solution 10 - C#

The answer provided by Zin Min solved my problem with a single line of code. Excellent!

I was having the same issue of converting a generic List to a generic ObservableCollection to use the values from my List to populate a ComboBox that is participating in binding via a factory class for a WPF Window.

_expediteStatuses = new ObservableCollection<ExpediteStatus>(_db.getExpediteStatuses());

Here is the signature for the getExpediteStatuses method:

public List<ExpediteStatus> getExpediteStatuses()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJosh CloseView Question on Stackoverflow
Solution 1 - C#eugene.sushilnikovView Answer on Stackoverflow
Solution 2 - C#Jeff MercadoView Answer on Stackoverflow
Solution 3 - C#Ivan SaloView Answer on Stackoverflow
Solution 4 - C#PraetorianView Answer on Stackoverflow
Solution 5 - C#Luke LowreyView Answer on Stackoverflow
Solution 6 - C#Zin MinView Answer on Stackoverflow
Solution 7 - C#Ejrr1085View Answer on Stackoverflow
Solution 8 - C#DamianView Answer on Stackoverflow
Solution 9 - C#JBrooksView Answer on Stackoverflow
Solution 10 - C#WolfDogView Answer on Stackoverflow