Как вы сортируете KeyedCollection? - PullRequest
3 голосов
/ 12 января 2011

В основном у меня есть KeyedCollection<string, CustomNode>, и я хочу иметь возможность сортировать коллекцию по ключу (или, желательно, с помощью специального компаратора).

Если это невозможно, может кто-топорекомендовать другой класс, где ключ встроен в значение, которое я могу отсортировать?

Ответы [ 6 ]

3 голосов
/ 25 мая 2011

Пришел этот вопрос при попытке решить похожую проблему. Если это все еще актуально, я смог реализовать сортировку, используя пример здесь:

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/56adc0f9-aa1b-4acf-8546-082bb01058f2/

В основном включает в себя сортировку основного списка коллекции. Сработал как шарм для меня.

Ура!

2 голосов
/ 12 января 2011

После получения дополнительной информации (см. Комментарии к answer выше), требуется сохранять сортировку «набора» по свойству элемента после изменения свойства.

В этом случаевы можете взглянуть на BindableLinq (есть и другие подобные структуры) и использовать реализованный там оператор OrderBy.

KeyedCollection<string, CustomNode> collection = /* from whereever */
collection.Items.AsBindable().OrderBy(c => c.PropertyOnCustomNode);

Пока ваше отредактированное свойство вызывает событие PropertyChanged, тогдаон немедленно применяет повторный заказ.Если вы хотите изменить свою коллекцию, убедитесь, что в исходной коллекции реализован INotifyCollectionChanged.

2 голосов
/ 12 января 2011

KeyCollection<T> наследуется от Collection<T>, который реализует IEnumerable, поэтому вы должны иметь возможность использовать IEnumerable.OrderBy().IEnumerable.OrderBy() также имеет перегрузку, которая позволяет вам предоставить пользовательский компаратор .

1 голос
/ 15 января 2014

Это основано на ссылке, предоставленной в ответе Дэном: http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/56adc0f9-aa1b-4acf-8546-082bb01058f2/

   public class RequestTemplate : IComparable<RequestTemplate>
   {
      // This is the primary key for the object
      private Guid _guidNumber;

      // This is what a collection of these objects should be sorted by
      private string _buttonCaption = "";


      public Guid GuidNumber
      {
         get { return _guidNumber; }
         set { _guidNumber = value; }  // Setter only provided for deserialization usage
      }

      public string ButtonCaption
      {
         get { return _buttonCaption; }
         set { _buttonCaption = value; }
      }


      /// <summary>
      /// Method needed to allow sorting a collection of these objects.
      /// </summary>
      public int CompareTo(RequestTemplate other)
      {
         return string.Compare(this.ButtonCaption, other.ButtonCaption, 
                               StringComparison.CurrentCultureIgnoreCase);
      }
   }


   public class RequestTemplateKeyedCollection : KeyedCollection<Guid, RequestTemplate>
   {
      /// <summary>
      /// Sort the collection by sorting the underlying collection, accessed by casting the Items 
      /// property from IList to List.
      /// </summary>
      public void Sort()
      {
         List<RequestTemplate> castList = base.Items as List<RequestTemplate>;
         if (castList != null)
            castList.Sort();  // Uses default Sort() for collection items (RequestTemplate)
      }


      /// <summary>
      /// Method needed by KeyedCollection.
      /// </summary>
      protected override Guid GetKeyForItem(RequestTemplate requestTemplate)
      {
         return requestTemplate.GuidNumber;
      }
   }

Пока еще не тестировали, но, похоже, все в порядке.

0 голосов
/ 12 января 2011

Вы можете взглянуть на коллекцию SortedDictionary ... Но это приведет к дополнительным расходам на поиск элементов O (log N), а не к коллекции KeyedCollection с получением O (1).

0 голосов
/ 12 января 2011

Почему бы просто не использовать SortedList<TKey, TValue> класс?

MSDN-ссылка

...