Skip to content

Instantly share code, notes, and snippets.

@tanitanin
Created November 12, 2018 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanitanin/7ca8dc8dff1d4c3919f70633f9f5d135 to your computer and use it in GitHub Desktop.
Save tanitanin/7ca8dc8dff1d4c3919f70633f9f5d135 to your computer and use it in GitHub Desktop.
ObservableSortedCollection<T>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
public class ObservableSortedCollection<T> :
ObservableCollection<T>
where T: IComparable<T>, INotifyPropertyChanged
{
#region Constructor
// 1つ目はそのまま
public ObservableSortedCollection() : base() { }
// 2つ目はひとつずつ追加する
public ObservableSortedCollection(IEnumerable<T> collection) : base()
{
foreach(var item in collection)
{
this.Add(item);
}
}
#endregion
#region IndexOf
// 同じ順位で最初のインデックス
public int FirstIndexOf(T item)
{
// "以上"になる最初のオブジェクトを選ぶ
return this.IndexOf(this.FirstOrDefault(x => x.CompareTo(item) >= 0));
}
// 同じ順位で最後のインデックス
public int LastIndexOf(T item)
{
// "以下"になる最後のオブジェクトを選ぶ
return this.IndexOf(this.LastOrDefault(x => x.CompareTo(item) <= 0));
}
#endregion
#region InsertItem, MoveItem
// 挿入
protected override void InsertItem(int _, T item)
{
var index = LastIndexOf(item) + 1;
base.InsertItem(index, item);
item.PropertyChanged += OnPropertyChanged; // イベント変更通知をつかむ
}
// 移動
protected override void MoveItem(int oldIndex, int _)
{
// 本来より前にある場合はfirstの手前につける
var firstIndex = this.FirstIndexOf(this[oldIndex]);
if(oldIndex < firstIndex)
{
base.MoveItem(oldIndex, firstIndex);
}
// 本来より後ろにある場合はlastの後ろにつける
var lastIndex = this.LastIndexOf(this[oldIndex]);
if (lastIndex < oldIndex)
{
base.MoveItem(oldIndex, lastIndex + 1);
}
// firstとlastの間にある場合は移動する必要がないので何もしない
}
#endregion
#region SetItem
// 変更
protected override void SetItem(int index, T item)
{
this[index].PropertyChanged -= OnPropertyChanged; // イベント変更通知を解除
base.SetItem(index, item);
base.MoveItem(index, 0);
item.PropertyChanged += OnPropertyChanged; // イベント変更通知を登録
}
#endregion
#region RemoveItem, ClearItems
// 削除
protected override void RemoveItem(int index)
{
this[index].PropertyChanged -= OnPropertyChanged; // イベント変更通知を解除
base.RemoveItem(index);
}
// クリア
protected override void ClearItems()
{
foreach(var item in this)
{
item.PropertyChanged -= OnPropertyChanged; // イベント変更通知を解除
}
base.ClearItems();
}
#endregion
#region OnPropertyChanged
// Tのプロパティ変更時に呼び出される
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(sender is T item)
{
this.MoveItem(IndexOf(item), 0);
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment