I'm converting a project from Windows Forms to WPF format. Currently, I've bounded all the data to elements. I now raise a problem in ObservableCollection
, saying:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
How can I make my code threadsafe? Or how do I guide the changes to the Dispatcher thread? I've seen a few posts about it but I'm confused on how to apply it on my own project. Maybe someone can shed some light on this for me?
This is my code of 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
}
}
EDIT: After the answer given by ywm I changed my AddRange
class to:
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);
}
Now, all my ObservableList's are null
.