web-dev-qa-db-ja.com

WP7でList <T>をObservableCollection <T>に変換します

遅すぎるのか、何なのかはわかりませんが、これを行う方法がわかりません...

私がすることを期待していること、そしてオブジェクトブラウザが言うことはそこにあります、これは次のとおりです:

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

しかし、ObservableCollection<T>には、単一のパラメーターなしのコンストラクターがあります。オブジェクトブラウザは、ListとIEnuerableを渡すことができるオーバーロードが2つあると言います。

セットアップに何か問題がありますか?コンストラクターは電話版ではありませんか? (それは奇妙だろう)

これが実際が存在しない場合、WP7でこれを行う標準的な方法は何ですか?

40
Josh Close

コンストラクター ObservableCollection<T>(IEnumerable<T>) および ObservableCollection<T>(List<T>) は、WP 7.0ではサポートされていません。 パラメータレスコンストラクター は、WP 7.0でサポートされています。他のコンストラクターは、Silverlight 4で使用可能です上記およびWP 7.1以降、WP 7.0。

一括して追加する方法は簡単に利用できないため、リストを取得してObservableCollectionの新しいインスタンスに個別にアイテムを追加することが唯一のオプションだと思います。ただし、これを拡張機能または静的メソッドに自分で組み込むことを妨げるものではありません。

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

ObservableCollectionには、List <T>またはIEnumerable <T>の入力パラメーターを持ついくつかのコンストラクターがあります。
List<T> list = new List<T>();
ObservableCollection<T> collection = new ObservableCollection<T>(list);

93

変換する List<T> list監視可能なコレクションには、次のコードを使用できます。

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

これを行うには、独自の拡張メソッドを作成する必要があります。

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

この回答の拡張メソッド IList <T>からObservableCollection <T> は非常にうまく機能します

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

多数のアイテムを追加する場合は、ObservableCollectionから独自のクラスを派生させ、保護されたItemsメンバーにアイテムを追加することを検討してください。これにより、オブザーバーでイベントが発生しません。完了したら、適切なイベントを発生させることができます。

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

UI要素(LongListSelectorなど)に既にバインドされているObservableCollectionに多くのアイテムを追加すると、パフォーマンスが大幅に向上する可能性があります。

項目を追加する前に、十分なスペースがあることを確認して、BulkObservableCollectionクラスにこのメソッドを実装し、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

拡張機能を作成したので、次の操作を行うだけでリストを含むコレクションを読み込むことができます。

MyObservableCollection.Load(MyList);

拡張子は次のとおりです。

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

これを使って:

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

Zin Minが提供した回答は、1行のコードで私の問題を解決しました。優れた!

ジェネリックリストをジェネリックObservableCollectionに変換して、リストの値を使用して、WPFウィンドウのファクトリクラスを介したバインディングに参加しているComboBoxを作成するという同じ問題を抱えていました。

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

GetExpediteStatusesメソッドのシグネチャは次のとおりです。

public List <ExpediteStatus> getExpediteStatuses()

0
WolfDog