Change UI display order of an ObservableCollection I have an ObservableCollection that is filled with custom elements of type Video runtime. These have the properties of Name, Rating and Number of Viewers.
I want to display the Video elements in different orders based on whichever of the three criteria the user chooses during Application Runtime. I created the following Enum to store the possible choices:

public enum OrderBy
{
    [Description("Video Name")]
    Name = 0,

    [Description("Video Rating")]
    Rating = 1,

    [Description("Number of Viewers")]
    ViewerNumber = 2
}


These are fed into a ComboBox called OrderCombo allowing the user to change the order criteria (I'm displaying the Description to the user):

foreach (var item in Enum.GetValues(typeof(OrderBy)))
{
    OrderCombo.Items.Add(((OrderBy)item).GetDescription());
}


To avoid sorting, I used LINQ to get the order and I came up with the following:

IOrderedEnumerable&lt;Video&gt; GetOrder()
    {
        switch (OrderCombo.SelectedIndex)
        {

            case 0:
                return videos.OrderBy(x =&gt; x.Name);

            case 1:
                return videos.OrderByDescending(x =&gt; x.Rating);

            case 2:
                return videos.OrderByDescending(x =&gt; x.NumberOfViewers);

        }
        return videos.OrderBy(x =&gt; x.Name);
    }


Then, I call this function every time a new element is added or an element is delelted or the user changes the order:

VideoUIElment.ItemsSource = GetOrder();


So basically I keep re-calculating the enumerable every time, which workswpf but I'm wondering if there is a more efficient/elegant way of doing this.
Maybe store the order in one or several Func&lt;&gt;s? I tried them, but they can only be of a (compile-time) fixed type as in Func&lt;Video, string&gt; for Name and I would rather avoid using implementations like Func&lt;Video, dynamic&gt;.
To sort your ObservableCollection you should be using data-binding and let WPF do the work.

First let's fix the ComboBox that you currently populate manually. For the sake of this review I assume you use your code-behind file as a data-source that is bound to the Window via:

DataContext="{Binding RelativeSource={RelativeSource Self}}"


Next you need to tell the ComboBox where to find the items and how to display them:

&lt;ComboBox 
    ItemsSource="{Binding OrderOptions}" 
    DisplayMemberPath="Description" 
    SelectedValuePath="OrderBy" 
    SelectionChanged="Selector_OnSelectionChanged"&gt;
&lt;/ComboBox&gt;


It receives the values from the code-behind property (you of course would read the descriptions here with your reflection helpers):

public IEnumerable&lt;OrderOption&gt; OrderOptions
{
    get
    {
        return
            Enum
                .GetValues(typeof(OrderBy))
                .Cast&lt;OrderBy&gt;()
                .Select(x =&gt; new OrderOption { OrderBy = x, Description = x.ToString() });
    }
}


I created a helper object for this combo-box that looks like this:

public class OrderOption
{
    public OrderBy OrderBy { get; set; }

    public string Description { get; set; }
}


Now we need a list of videos:

private ObservableCollection&lt;Video&gt; _videos = new ObservableCollection&lt;Video&gt;(new[]
{
    new Video { Name = "Rambo", Rating = 3},
    new Video { Name = "Rocky", Rating = 8},
    new Video { Name = "Turbo Interceptor", Rating = 1}
});


where the Video is implemented as:

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

    public int Rating { get; set; }
}


and the code-behind file has this property:

public ObservableCollection&lt;Video&gt; Videos =&gt; _videos;


Now comes the tricky part. You need to add a new resource to the resource-dictionary. This is a CollectionViewSource that initially will sort the items by Name. 

&lt;Window.Resources&gt;
    &lt;ResourceDictionary&gt;
        &lt;CollectionViewSource x:Key="SortedVideos" Source="{Binding Videos}"&gt;
            &lt;CollectionViewSource.SortDescriptions&gt;
                &lt;scm:SortDescription PropertyName="Name"&gt;&lt;/scm:SortDescription&gt;
            &lt;/CollectionViewSource.SortDescriptions&gt;
        &lt;/CollectionViewSource&gt;
    &lt;/ResourceDictionary&gt;
&lt;/Window.Resources&gt;


In order for this to work you need to add a new namespace:

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"


Now you can bind a ListView to it:

&lt;ListView 
    ItemsSource="{Binding Source={StaticResource SortedVideos}}" 
    DisplayMemberPath="Name"&gt;
&lt;/ListView&gt;


You have probably noticed the combo-box has this Selector_OnSelectionChanged event handler that in code-behind is implemented like this to get the currently select OrderBy, then the switch is used to change the sorting by first clearing the current settings and adding a new one that changes the property of the Video object that is used for sorting. In this example I only used the Name and the Rating. Now each time you change the selection WPF will update the ListView and if you add or delete an item it will use the current setting to re-order it.

private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var colView = Resources["SortedVideos"] as CollectionViewSource;
    switch (((sender as ComboBox).SelectedItem as OrderOption).OrderBy)
    {
        case OrderBy.Name:
            colView.SortDescriptions.Clear();
            colView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
            break;
        case OrderBy.Rating:
            colView.SortDescriptions.Clear();
            colView.SortDescriptions.Add(new SortDescription("Rating", ListSortDirection.Ascending));
            break;
    }
}