开发者

How do you sort a KeyedCollection<TKey, TItem>?

Basically I've got a KeyedCollection<string, CustomNode开发者_StackOverflow社区>, and I want to be able to sort the collection by the key (or preferably with a custom comparer).

If this isn't possible, can someone recommend another class where the key is embedded in the value that I can sort?


Upon further information (see comments on answer above), a requirement is to keep the "set" sorted by a element's property after the property is edited.

In this case, you might take a look at BindableLinq (there are other similar frameworks too) and use the OrderBy statement implemented in there.

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

As long as your edited property raises a PropertyChanged event then it'll apply the re-ordering immediately. If you wish to change your collection, then ensure that the source collection implements INotifyCollectionChanged.


Came this question while trying to solve a similar problem. If it is still relevant, I was able to implement Sort using the example here:

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

Basically involves sorting the underlying List of the collection. Worked like a charm for me.

Cheers!


KeyCollection<T> inherits from Collection<T> which implements IEnumerable so you should be able to use IEnumerable.OrderBy(). IEnumerable.OrderBy() also has an overload that allows you to supply a custom comparer.


This is based on the link provided in the answer by Dan: 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;
      }
   }

Haven't tested it extensively yet, but it seems to work OK.


You might look at the SortedDictionary collection... But that'll come with added expense for item retrieval O(log N) as opposed to a KeyedCollection with O(1) retrieval.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜