要素数制限ObservableCollection
ログ等を蓄積して画面に表示する為に ObservableCollection を使用する時に、蓄積データ数に制限をかけられるクラスを ObservableCollection をベースに作りました。 データを足して行った時に、所定数を超えると古い要素が削除されます。
要素数制限付きObservableCollection
ObservableCollection
- 要素数の制限値である Limit を作成します。
- 要素数を Limit に抑えるためのメソッド Shrink を追加します。 Shrink では、要素が先頭に挿入された時には最後を、それ以外に加えられた時には先頭を削除します。
- InsertItem(int index, string item) を override します。 insert される文字列には、先頭に現在時刻を付加します。 Shrink の引数に index を渡して、Limit を超えた時の削除位置が変わるようにします。
public class SizeLimitStringCollection : ObservableCollection<string> { protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); return true; } protected virtual void Shrink(int index) { if (index != 0) { while (Limit < Count) RemoveAt(0); } else { while (Limit < Count) RemoveAt(Count - 1); } } private int limit = 100; public int Limit { get { return limit; } set { if (value < 1) value = 1; if (SetProperty(ref limit, value)) { Shrink(Count); } } } protected override void InsertItem(int index, string item) { item = DateTime.Now.ToString("hh:MM:ss ") + item; base.InsertItem(index, item); Shrink(index); } }
使い方
LogCollection を作成します。
private SizeLimitStringCollection logCollection = new SizeLimitStringCollection(); public SizeLimitStringCollection LogCollection { get { return logCollection; } set { SetProperty(ref logCollection, value); } }
先頭にログを追加する時には
LogCollection .inseret(0, LogString) とします。最後尾にログを追加する時には
LogCollection .add(LogString) とします。
別スレッドからのアクセス
ObservableCollectionはUIスレッドにあるので、別スレッドから操作する時にはDispatcherを使用します。 その為には以下のメソッドを作っておいて呼び出してあげます。
public void SetLog(string st) { System.Windows.Application.Current.Dispatcher.BeginInvoke( new Action(() => LogCollection.Insert(0, st))); }
サンプルアプリケーション
SizeLimitStringCollection を使ったサンプルアプリを作りました。
ソースコードは下記にあります。