PG日誌

各記事はブラウザの横幅を1410px以上にすると2カラムの見出しが表示されます。なるべく横に広げてみてください。

ObservableCollectionにAddRangeを追加する

タイトルの通りで、ObservableCollectionやIListにはAddRangeを追加したいと思います。

ObservableCollectionにはAddRangeが存在しないため、リストで受け取ったデータはforeachで一つひとつ追加することになり多少面倒なので「拡張メソッド」という機能を使ってObservableCollectionにAddRangeメソッドを追加したいと思います。

using System.Collections.ObjectModel;

// 配列用の汎用機能を提供します。
public static class ArrayUtility
{
    // 指定したシーケンスをすべて追加する。
    public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> collection)
    {
        foreach (var item in target)
        {
            collection.Add(item);
        }
    }

    /// <summary>
    /// 指定したコレクションを変換して格納します。
    /// </summary>
    public static void AddRange<T, S>(this ObservableCollection<T> collection, IEnumerable<S> target, Func<S, T> convert)
    {
        foreach (var item in target)
        {
            collection.Add(convert(item));
        }
    }
}

使い方は以下の通り。

// AddRangeするリスト
var src = new ObservableCollection<int>() { 1, 2, 3, 4, 5 };

// 追加するリスト
var list = new List<int>() { 11, 12, 13, 14, 15 };
src.AddRange(list);
// >  1, 2, 3, 4, 5, 11, 12, 13, 14, 15:全部追加される
}|<

もう一つの引数に「Func<S, T> convert」のほうは以下のように使用します。

先ほどとほぼ同じですが、ラムダ式を指定することで追加するときに変換しながら追加することができるようになります。

>|cs|
var src = new ObservableCollection<int>() { 1, 2, 3, 4, 5 };

// 追加するリスト
var list = new List<int>() { 11, 12, 13, 14, 15 };
src.AddRange(list, p => p + 1000/*追加するときに1000を加算する*/);
// >  1, 2, 3, 4, 5, 1011, 1012, 1013, 1014, 1015

最後になりますが、この方法ちょっとだけパフォーマスが悪いのです。何故なら追加するたびにCollectionChangedイベントが発生して通知が飛ぶからです。XAMLのItemsSourceにバインドしてるとリストの件数が多いとちょっとした事故になるのでご注意下さい。