web-dev-qa-db-fra.com

Convertir la liste <T> en ObservableCollection <T> dans WP7

Je ne sais pas s'il est trop tard ou quoi, mais je ne vois pas comment faire cela ...

Voici ce que je compte faire et ce que dit le navigateur d'objets:

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

Mais ObservableCollection<T> a un seul constructeur sans paramètre. Le navigateur d’objets indique qu’il existe 2 surcharges où List et IEnuerable devraient pouvoir être passés.

Y at-il quelque chose de mal avec ma configuration? Les constructeurs ne sont pas sur la version de téléphone? (ce serait étrange)

Si ce vraiment n'existe pas, quelle est la méthode standard pour le faire avec WP7 maintenant?

39
Josh Close

Les constructeurs ObservableCollection<T>(IEnumerable<T>) et ObservableCollection<T>(List<T>) ne sont pas pris en charge dans WP 7.0. Seul le constructeur paramètre sans paramètre est pris en charge dans WP 7.0. Les autres constructeurs sont disponibles dans Silverlight 4 et versions ultérieures et dans WP 7.1 et versions supérieures, mais pas dans WP 7.0.

Je suppose que votre seule option est de prendre votre liste et d’ajouter les éléments dans une nouvelle instance de ObservableCollection individuellement car il n’existe pas de méthode facilement disponible pour les ajouter en bloc. Bien que cela ne vous empêche pas de le mettre vous-même dans une extension ou une méthode statique.

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

Pour convertir List<T> list en collection observable, vous pouvez utiliser le code suivant:

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

Pour ce faire, vous devrez écrire votre propre méthode d'extension:

    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;
      }
    }
9
Praetorian

La méthode d'extension de cette réponse IList <T> à ObservableCollection <T> fonctionne plutôt bien

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;
}
6
Luke Lowrey
ObservableCollection<FacebookUser_WallFeed> result = new ObservableCollection<FacebookUser_WallFeed>(FacebookHelper.facebookWallFeeds);
3
Zin Min

Si vous envisagez d'ajouter de nombreux éléments, pensez à dériver votre propre classe de ObservableCollection et à ajouter des éléments au membre protégé Items - cela ne déclenche pas d'événements dans les observateurs. Lorsque vous avez terminé, vous pouvez soulever les événements appropriés:

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"));
    }
 }

L'ajout de nombreux éléments à une ObservableCollection déjà liée à un élément d'interface utilisateur (tel que LongListSelector) peut avoir un impact considérable sur les performances.

Avant d'ajouter les éléments, vous pouvez également vous assurer que vous disposez de suffisamment d'espace pour que la liste ne soit pas développée en permanence en implémentant cette méthode dans la classe BulkObservableCollection et en l'appelant avant d'appeler AddRange:

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

J'ai créé une extension et je peux maintenant charger une collection avec une liste en faisant:

MyObservableCollection.Load(MyList);

L'extension est:

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;
   }
}
1
JBrooks

La réponse fournie par Zin Min a résolu mon problème avec une seule ligne de code. Excellent!

J'avais le même problème de conversion d'une liste générique en un ObservableCollection générique afin d'utiliser les valeurs de ma liste pour remplir un contrôle ComboBox participant à la liaison via une classe fabrique pour une fenêtre WPF.

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

Voici la signature de la méthode getExpediteStatuses:

liste publique <ExpediteStatus> getExpediteStatuses ()

0
WolfDog