Created
November 12, 2018 15:54
-
-
Save tanitanin/7ca8dc8dff1d4c3919f70633f9f5d135 to your computer and use it in GitHub Desktop.
ObservableSortedCollection<T>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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