Преобразовать список <T>в коллекцию ObservableCollection <T>в WP7 - PullRequest
40 голосов
/ 06 апреля 2011

Я не знаю, уже слишком поздно или как, но я не понимаю, как это сделать ...

То, что я ожидаю сделать, и что там говорит браузер объектов, это:

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

Но ObservableCollection<T> имеет один конструктор без параметров. Обозреватель объектов говорит, что есть 2 перегрузки, в которые должны быть переданы List и IEnuerable.

Что-то не так с моей настройкой? Разве конструкторы не в версии для телефона? (это было бы странно)

Если этого на самом деле не существует, каков сейчас стандартный способ сделать это с WP7?

Ответы [ 10 ]

90 голосов
/ 25 апреля 2013

ObservableCollection имеет несколько конструкторов, которые имеют входной параметр List или IEnumerable :
List<T> list = new List<T>();
ObservableCollection<T> collection = new ObservableCollection<T>(list);

33 голосов
/ 06 апреля 2011

Конструкторы 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);
14 голосов
/ 14 декабря 2012

Для преобразования List<T> list в наблюдаемую коллекцию вы можете использовать следующий код:

var oc = new ObservableCollection<T>();
list.ForEach(x => oc.Add(x));
8 голосов
/ 06 апреля 2011

Вы должны написать свой собственный метод расширения, чтобы сделать это:

    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;
      }
    }
6 голосов
/ 06 апреля 2011

Метод расширения из этого ответа IList до ObservableCollection работает довольно хорошо

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;
}
3 голосов
/ 25 декабря 2012
ObservableCollection<FacebookUser_WallFeed> result = new ObservableCollection<FacebookUser_WallFeed>(FacebookHelper.facebookWallFeeds);
2 голосов
/ 08 января 2017

Я сделал расширение, так что теперь я могу просто загрузить коллекцию со списком, выполнив:

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 голосов
/ 06 апреля 2011

Если вы собираетесь добавлять много элементов, рассмотрите возможность получения своего собственного класса из 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"));
    }
 }

При добавлении многих элементов в ObservableCollection, которая уже связана с элементом пользовательского интерфейса (например, LongListSelector), это может существенно повлиять на производительность.

Перед добавлением элементов вы также можете убедиться, что у вас достаточно места, чтобы список не расширялся непрерывно, реализовав этот метод в классе BulkObservableCollection и вызвав его до вызова AddRange:

    public void IncreaseCapacity(int increment)
    {
        var itemsList = (List<T>)Items;
        var total = itemsList.Count + increment;
        if (itemsList.Capacity < total)
        {
            itemsList.Capacity = total;
        }
    }
0 голосов
/ 12 июня 2019

Используйте это:

List<Class1> myList;
ObservableCollection<Class1> myOC = new ObservableCollection<Class1>(myList);
0 голосов
/ 24 января 2015

Ответ, предоставленный Zin Min, решил мою проблему с помощью одной строки кода. Отлично!

У меня возникла та же проблема преобразования общего списка в универсальную коллекцию ObservableCollection, чтобы использовать значения из моего списка для заполнения ComboBox, который участвует в привязке через класс фабрики для окна WPF.

_expediteStatuses = new ObservableCollection (_ db.getExpediteStatuses ());

Вот подпись для метода getExpediteStatuses:

общий список getExpediteStatuses ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...