Reputation: 20127
Basically I've got a KeyedCollection<string, CustomNode>
, 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?
Upvotes: 3
Views: 3833
Reputation: 11658
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.
Upvotes: 1
Reputation: 377
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!
Upvotes: 2
Reputation: 245429
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.
Upvotes: 1
Reputation: 15579
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.
Upvotes: 2
Reputation: 15579
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.
Upvotes: -1