WPF ObservableCollectionのチューニング
WPFがもっさりしているのでいろいろ検索している中でなるほどーとなったもの、大事そうなのでメモします。
Twelve Ways to Improve WPF Performance | Pelebyte
ObservableCollectionでこんなようなことをしてたとして。
using System.ComponentModel; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Nmdm { public sealed class AboutObservableCollectionTuning : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public ObservableCollection<Person> Persons { get; } /// <summary> /// 公開しているObservableCollectionを更新するなにかの処理 /// </summary> public void UpdatePersons() { // コレクションを初期化する。 this.Persons.Clear(); // メソッドの戻り値をコレクションに追加する。 foreach(var obj in this.GetPersons()) { // Addメソッドの度に変更通知が発生する。 this.Persons.Add(obj); } } /// <summary> /// 更新結果を取得するダミーの処理 /// </summary> private IEnumerable<Person> GetPersons() { return new Person[] { }; } } }
以下のようにする。(元の記事と全然違うけど・・・)
using System.ComponentModel; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Nmdm { public sealed class AboutObservableCollectionTuning : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public ObservableCollection<Person> Persons { get; private set; } /// <summary> /// 公開しているObservableCollectionを更新するなにかの処理 /// </summary> public void UpdatePersons() { // コレクションの空のインスタンスを生成 var updatedPersons = new ObservableCollection<Person>(); // メソッドの戻り値をコレクションに追加する。 foreach(var obj in this.GetPersons()) { updatedPersons.Add(obj); } // プロパティに張り替える。 this.Persons = updatedPersons; // 変更通知出す(必要あり?) if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Persons))); } /// <summary> /// 更新結果を取得するダミーの処理 /// </summary> private IEnumerable<Person> GetPersons() { return new Person[] { }; } } }
書き方の良しあしは別として、
大事なのはAddメソッドの度に変更通知を飛ばさないようにしよう。
ということですね。なるほどなるほど。