1

I need to sort an ObservableCollection after populatior alphabetically, suppose that inside I've this model:

class Nation
{
    public string Name { get; set; }
}

and this is my ObservableCollection:

ObservableCollection<Nation> ob = new ObservableCollection<Nation>();

suppose that inside I've three items with this order:

  1. England
  2. Afghanistan
  3. Italy

I need to sort it alphabetically, so I tried to:

ob.OrderBy(c => c.Name);

but I get no effect, when it should be:

  1. Afghanistan
  2. England
  3. Italy

What I did wrong?

AgainMe
  • 760
  • 4
  • 13
  • 33
  • 7
    You have to assign the result to something, it returns a sorted collection. `var sortedOb = ob.OrderBy(c => c.Name);` – Igor Sep 09 '16 at 13:33
  • @Igor so should be: `ob = ob.OrderBy(c => c.Name);`? – AgainMe Sep 09 '16 at 13:34
  • You would have to convert it back to an `ObservableCollection` as `OrderBy` returns an `IEnumerable`. – Igor Sep 09 '16 at 13:35
  • @Igor I though that `.OrderBy` reorder the original collection, instead of return new one. – AgainMe Sep 09 '16 at 13:36
  • 1
    @AgainMe Every LINQ method generates a new enumerable instead of modifying the original one – Matias Cicero Sep 09 '16 at 13:37
  • 2
    @AgainMe No - it returns an _iterator_ that wrpas the original collection, returning their elements in the specified order _when you loop over it_. – D Stanley Sep 09 '16 at 13:38

2 Answers2

6

bind your ObservableCollection to a CollectionViewsource, add a sort on it, then use that CollectionViewSource as the ItemSource of a Control.

Use CollectionViewSource to Sort

<CollectionViewSource x:Key='src' Source="{Binding ob}">
        <CollectionViewSource.SortDescriptions>
            <componentModel:SortDescription PropertyName="Name" />
        </CollectionViewSource.SortDescriptions>
 </CollectionViewSource>

Sample usage

<ListView ItemsSource="{Binding Source={StaticResource src}}" >
Eldho
  • 7,795
  • 5
  • 40
  • 77
3
var ob = new ObservableCollection<Nation>
{
    new Nation {Name = "Sweden"},
    new Nation {Name = "Afghanistan"},
    new Nation {Name = "England"},
    new Nation {Name = "Albania"},
};

var sorted = ob.OrderBy(n => n.Name);

sorted is IEnumerable and sorted, if you still need it as ObservableCollection just pass it to the constructor as described here.

Community
  • 1
  • 1
Marcus
  • 8,230
  • 11
  • 61
  • 88