Sorting outside the collection
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (Settings.AscendingSort.Value)
{
App.PictureList.Pictures = new ObservableCollection<Models.Picture>(App.PictureList.Pictures.OrderBy(x => x.DateTaken)) as System.Collections.IList;
Recent.ItemsSource = App.PictureList.Pictures;
}
else
{
App.PictureList.Pictures = new ObservableCollection<Models.Picture>(App.PictureList.Pictures.OrderByDescending(x => x.DateTaken)) as System.Collections.IList;
Recent.ItemsSource = App.PictureList.Pictures;
}
}
Sort on the XAML View
http://msdn.microsoft.com/en-us/library/ms742542.aspx
// You can sort the view of the collection rather that sorting the collection itself
// xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
<myView.Resources>
<CollectionViewSource x:Key="ItemListViewSource" Source="{Binding Itemlist}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="{Binding SortingProperty}" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</myView.Resources>
And then you can use the CollectionViewSource as ItemSource:
ItemsSource="{Binding Source={StaticResource ItemListViewSource}}"
Sorted Observable Collection
namespace SortedCollection
{
/// <summary>
/// SortedCollection which implements INotifyCollectionChanged interface and so can be used
/// in WPF applications as the source of the binding.
/// </summary>
/// <author>consept</author>
public class SortedObservableCollection<TValue> : SortedCollection<TValue>, INotifyPropertyChanged, INotifyCollectionChanged
{
public SortedObservableCollection() : base() { }
public SortedObservableCollection(IComparer<TValue> comparer) : base(comparer) { }
// Events
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (this.CollectionChanged != null)
{
this.CollectionChanged(this, e);
}
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index)
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex)
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex));
}
private void OnCollectionReset()
{
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
private void OnPropertyChanged(string propertyName)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public override void Insert(int index, TValue value)
{
base.Insert(index, value);
this.OnPropertyChanged("Count");
this.OnPropertyChanged("Item[]");
this.OnCollectionChanged(NotifyCollectionChangedAction.Add, value, index);
}
public override void RemoveAt(int index)
{
var item = this[index];
base.RemoveAt(index);
this.OnPropertyChanged("Item[]");
this.OnPropertyChanged("Count");
this.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index);
}
public override TValue this[int index]
{
get
{
return base[index];
}
set
{
var oldItem = base[index];
base[index] = value;
this.OnPropertyChanged("Item[]");
this.OnCollectionChanged(NotifyCollectionChangedAction.Replace, oldItem, value, index);
}
}
public override void Clear()
{
base.Clear();
OnCollectionReset();
}
}
}
Example
/*
* samples:
* //sort ascending
* MySortableList.Sort(x => x.Name, SortDirection.Ascending);
*
* //sort descending
* MySortableList.Sort(x => x.Name, SortDirection.Descending);
*/
public enum SortDirection
{
Ascending,
Descending
}
public class SortableObservableCollection : ObservableCollection
{
#region Consts, Fields, Events
#endregion
#region Methods
public void Sort(Func keySelector, SortDirection direction)
{
switch (direction)
{
case SortDirection.Ascending:
{
applySort(Items.OrderBy(keySelector));
break;
}
case SortDirection.Descending:
{
applySort(Items.OrderByDescending(keySelector));
break;
}
}
}
public void Sort(Func keySelector, IComparer comparer)
{
applySort(Items.OrderBy(keySelector, comparer));
}
private void applySort(IEnumerable sortedItems)
{
var sortedItemsList = sortedItems.ToList();
foreach (var item in sortedItemsList)
{
Move(IndexOf(item), sortedItemsList.IndexOf(item));
}
}
#endregion
}
///
/// Provides automatic sorting, when items are added/removed
///
///
public class SortedObservableCollection : SortableObservableCollection
{
#region Consts, Fields, Events
private readonly IComparer _comparer;
#endregion
#region Methods
public SortedObservableCollection(IComparer comparer)
{
Condition.Requires(comparer, “
comparer”).
IsNotNull();
_comparer = comparer;
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
Sort();
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
Sort();
}
public void Sort()
{
Sort(item => item, _comparer);
}
#endregion
}
///
/// Whenever a property of the item changed, a sorting will be issued.
///
///
public class SortedObservableCollectionEx : SortedObservableCollection where T : class, INotifyPropertyChanged
{
#region Consts, Fields, Events
#endregion
#region Methods
public SortedObservableCollectionEx(IComparer comparer)
: base(comparer)
{
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
if (item != null)
{
item.PropertyChanged += handleItemPropertyChanged;
}
}
protected override void RemoveItem(int index)
{
T item = this[index];
if (item != null)
{
item.PropertyChanged -= handleItemPropertyChanged;
}
base.RemoveItem(index);
}
private void handleItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Sort();
}
#endregion
}