以前WPFにバインディングされたObservableCollectionを他スレッドから操作すると例外になる
件で悩んだ以後、CollectionのAdd/Removeはせずに毎回Collectionを作り直すという消極策に出ていたのですが、今回どうやら避けて通れない事態に。View側でCollectionChangedイベント監視するの面倒だなぁと思ってたら、答え
は意外にも簡単なところに。去年もうちょっとちゃんと調べればよかった。
なんとなくViewModel/ModelがViewの事情に譲歩しているような気もしますが、これくらいなら個人的には許容範囲。(UIスレッドのDispatcher得るためにViewとViewModelに細工しないといけないならやるか悩んだかも)
[2018/4/23 追記] .NET Framework 4.5以上ではBindingOperations.EnableCollectionSynchronization
を使ったほうが楽でしょう。私も場合、いまだにXPで動いている案件が有ったりするので…
using System.Collections.ObjectModel;
using System.Windows.Threading;
class DispatchedCollection<T> : ObservableCollection<T>
{
Dispatcher uiDispatcher = System.Windows.Application.Current.Dispatcher;
protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (uiDispatcher.CheckAccess())
{
base.OnCollectionChanged(e);
}
else
{
uiDispatcher.Invoke(new Action(() => base.OnCollectionChanged(e)));
}
}
}
















Comments