web-dev-qa-db-ger.com

Konvertieren Sie in WP7 die Liste <T> in ObservableCollection <T>

Ich weiß nicht, ob es gerade zu spät ist oder was, aber ich sehe nicht, wie ich das machen soll ...

Was ich erwarte, und was der Objektbrowser sagt, ist dort:

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

ObservableCollection<T> hat jedoch einen einzigen parameterlosen Konstruktor. Der Objektbrowser sagt, dass es zwei Überladungen gibt, an die List und IEnuerable übergeben werden können.

Stimmt etwas nicht mit meinem Setup? Befinden sich die Konstruktoren nicht in der Telefonversion? (das wäre seltsam)

Wenn dies wirklich nicht existiert, wie ist dies jetzt bei WP7 üblich?

39
Josh Close

Die Konstruktoren ObservableCollection<T>(IEnumerable<T>) und ObservableCollection<T>(List<T>) werden in WP 7.0 nicht unterstützt. Nur der parameterless-Konstruktor wird in WP 7.0 unterstützt. Die anderen Konstruktoren sind in Silverlight 4 und höher und WP 7.1 und höher verfügbar, jedoch nicht in WP 7.0.

Ich denke, Ihre einzige Möglichkeit ist, Ihre Liste zu übernehmen und die Elemente einzeln in eine neue Instanz einer ObservableCollection aufzunehmen, da es keine leicht verfügbaren Methoden gibt, um sie in großen Mengen hinzuzufügen. Dies soll Sie jedoch nicht davon abhalten, dies selbst in eine Erweiterungs- oder statische Methode zu integrieren.

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

ObservableCollection verfügt über mehrere Konstruktoren mit den Eingabeparametern List <T> oder IEnumerable <T>:
List<T> list = new List<T>();
ObservableCollection<T> collection = new ObservableCollection<T>(list);

93

Um List<T> list in eine beobachtbare Sammlung umzuwandeln, können Sie folgenden Code verwenden:

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

Sie müssen dazu eine eigene Erweiterungsmethode schreiben:

    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

Erweiterungsmethode aus dieser Antwort IList <T> zu ObservableCollection <T> funktioniert ziemlich gut

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

Wenn Sie viele Elemente hinzufügen möchten, sollten Sie in Betracht ziehen, Ihre eigene Klasse von ObservableCollection abzuleiten und dem geschützten Elements-Element Elemente hinzuzufügen. Dadurch werden keine Ereignisse in Beobachtern ausgelöst. Wenn Sie fertig sind, können Sie die entsprechenden Ereignisse ansprechen:

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

Wenn Sie einer ObservableCollection, die bereits an ein UI-Element (z. B. LongListSelector) gebunden ist, viele Elemente hinzufügen, kann sich dies erheblich auf die Leistung auswirken.

Vor dem Hinzufügen der Elemente können Sie außerdem sicherstellen, dass Sie über ausreichend Speicherplatz verfügen, sodass die Liste nicht kontinuierlich erweitert wird, indem Sie diese Methode in der BulkObservableCollection-Klasse implementieren und vor dem Aufrufen von AddRange aufrufen:

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

Benutze das:

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

Ich habe eine Erweiterung erstellt, sodass ich jetzt eine Sammlung mit einer Liste laden kann, indem

MyObservableCollection.Load(MyList);

Die Erweiterung lautet:

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

Die Antwort von Zin Min löste mein Problem mit einer einzigen Codezeile. Ausgezeichnet!

Ich hatte das gleiche Problem, eine generische Liste in eine generische ObservableCollection zu konvertieren, um die Werte aus meiner Liste zu verwenden, um eine ComboBox aufzufüllen, die über eine Factory-Klasse für ein WPF-Fenster an der Bindung beteiligt ist.

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

Hier ist die Signatur für die getExpediteStatuses-Methode:

public List <ExpediteStatus> getExpediteStatuses ()

0
WolfDog