Sortable Observable Collection in C#
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 }
Sortable Observable Collection in C#的更多相关文章
- Reactive Extensions介绍
Reactive Extensions(Rx)是对LINQ的一种扩展,他的目标是对异步的集合进行操作,也就是说,集合中的元素是异步填充的,比如说从Web或者云端获取数据然后对集合进行填充.Rx起源于M ...
- 《Entity Framework 6 Recipes》中文翻译系列 (24) ------ 第五章 加载实体和导航属性之查询内存对象
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-4 查询内存对象 问题 你想使用模型中的实体对象,如果他们已经加载到上下文中, ...
- A Xamarin.Forms Infinite Scrolling ListView
from:http://www.codenutz.com/lac09-xamarin-forms-infinite-scrolling-listview/ The last few months ha ...
- Data Binding(数据绑定)用户指南
1)介绍 这篇文章介绍了如何使用Data Binding库来写声明的layouts文件,并且用最少的代码来绑定你的app逻辑和layouts文件. Data Binding库不仅灵活而且广泛兼容- 它 ...
- Reactive ExtensionsLINQ和Rx简单介绍
LINQ和Rx简单介绍 相信大家都用过Language Integrated Query (LINQ),他是一种强大的工具能够从集合中提取数据.Reactive Extensions(Rx)是对LIN ...
- Reactive Extensions
Rx提供了一种新的组织和协调异步事件的方式,极大的简化了代码的编写.Rx最显著的特性是使用可观察集合(Observable Collection)来达到集成异步(composing asynchron ...
- How to Add Columns to a DataGrid through Binding and Map Its Cell Values
How to Add Columns to a DataGrid through Binding and Map Its Cell Values Lance Contreras, 7 Nov 2013 ...
- lightswitch 添加 TreeView 控件
代码片段 <UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk&q ...
- (MVVM) ListBox Binding 和 实时刷新
当需要用Lisbbox 来log 一些记录的时候,ObservableCollection 并不可以是记录实时的反应在WPF 的UI上面. 这个时候就需要用一个异步collection 来完成. // ...
随机推荐
- (四)WebRTC手记之本地音频采集
转自:http://www.cnblogs.com/fangkm/p/4374668.html 上一篇博文介绍了本地视频采集,这一篇就介绍下音频采集流程,也是先介绍WebRTC原生的音频采集,再介绍C ...
- Codeforces Round #143 (Div. 2) E. Cactus 无向图缩环+LCA
E. Cactus A connected undirected graph is called a vertex cactus, if each vertex of this graph bel ...
- 驱动中获取PsActiveProcessHead变量地址的五种方法也可以获取KdpDebuggerDataListHead
PsActiveProcessHead的定义: 在windows系统中,所有的活动进程都是连在一起的,构成一个双链表,表头是全局变量PsActiveProcessHead,当一个进程被创建时,其Act ...
- 【T_SQL】基础 续+
十.模糊查询 1.LIKE --查询时,字段中的内容并不一定与查询内容完全匹配,只要字段中含有这些内容. SELECT StuName AS 姓名 FROM Stuinfo WHERE stuname ...
- RTTI (Run-Time Type Identification,通过运行时类型识别) 转
参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个 ...
- TweenMax参数补充
构造函数:TweenMax(target:Object, duration:Number, vars:Object) target:Object -- 需要缓动的对象 duration:Number ...
- AOP动态代理解析1-标签的解析
spring.handlers http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespa ...
- 内核终端判断,微信?QQ?ipad?IE?移动?Google?opera……
$(document).ready(function(){ //判断访问终端 var browser={ versions:function(){ var u = navigator.userAgen ...
- 转 Delphi Invalidate的用法
1.Invalidate介绍 void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口 ...
- 【bzoj3624】【apio2008】免费道路
2016/06/25 诸老师讲的图论,听了这道题很想写一下,但是看来要留到期末考后了. 07/01 有的标记是说生成树,有的是并查集...然而我只是觉得这棵奇怪的生成树蛮精妙的... 题目比较难过的只 ...