プロジェクトをWindowsフォームからWPF形式に変換しています。現在、すべてのデータを要素にバインドしています。私は今、次のように問題を提起しObservableCollection
ます:
このタイプのCollectionViewは、Dispatcherスレッドとは異なるスレッドからのSourceCollectionへの変更をサポートしていません。
コードをスレッドセーフにするにはどうすればよいですか?または、ディスパッチャスレッドへの変更をどのようにガイドしますか?私はそれについていくつかの投稿を見ましたが、私はそれを自分のプロジェクトに適用する方法について混乱しています。多分誰かが私のためにこれにいくつかの光を当てることができますか?
これは私のコードですObservableList.cs
:
public class ObservableList<T> : ObservableCollection<T>
{
#region Private members
bool isInAddRange = false;
#endregion Private members
#region Public methods
/// <summary>
/// Creates a new empty ObservableList of the provided type.
/// </summary>
public ObservableList()
{
}
/// <summary>
/// Handles the event when a collection has changed.
/// </summary>
/// <param name="e"></param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// intercept this when it gets called inside the AddRange method.
if (!isInAddRange)
base.OnCollectionChanged(e);
}
/// <summary>
/// Adds a collection of items to the ObservableList.
/// </summary>
/// <param name="items"></param>
public void AddRange(IEnumerable<T> items)
{
isInAddRange = true;
foreach (T item in items)
{
Add(item);
}
isInAddRange = false;
var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,items.ToList());
base.OnCollectionChanged(e);
}
#endregion Public methods
}
}
編集:ywmによって与えられた答えの後、私はAddRange
クラスを次のように変更しました:
public void AddRange(IEnumerable<T> items)
{
isInAddRange = true;
foreach (T item in items)
{
if (item != null)
{
Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
Add(item);
}));
}
}
isInAddRange = false;
var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,items.ToList());
base.OnCollectionChanged(e);
}
これで、すべてのObservableListはnull
です。