I\'m hoping to be able to reject some items after they have been added to an ObservableCollection. I am not able to subclass the ObservableCollection or use any sort of view, s
I had tried using setting a flag to request collection add/remove changes and then when the System.Windows.Interop.ComponentDispatcher.ThreadIdle called my handler, doing my add or remove. That works. However, using a try-finally in the collection changed handler to unwire and then rewire that same collection changed event handler also bypassed the re-entrance issue:
private void MyDataGrid_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e )
{
try
{
dgRows.CollectionChanged -= MyDataGrid_CollectionChanged;
switch( e.Action )
{
case NotifyCollectionChangedAction.Add:
if( SomeTestIsTrue() )
dgRows.Add( new vmRowObject() );
break;
}
}
finally
{
dgRows.CollectionChanged += MyDataGrid_CollectionChanged;
}
}
use a ToList()
in order to iterate over the list.
foreach(var item in collection.ToList())
{
if(item.Name == "Fred")
{
collection.Remove(item);
}
}
Check out Common Mistakes using Observable Collection.
Having said that, if you still want to go this route - you can spin a new Thread
if you really want to modify a collection you are going to want to iterate through a copy of the collection. its because you are trying to modify the collection in the foreach loop thats causing you grief.
example
var copy = new ObservableCollection<YourType>(collection)
foreach(var item in copy)
{
if(item.Name == "Fred")
{
collection.Remove(item);
}
}
that said, I agree with Anurag that you shouldn't be doing this type of thing with an observablecollection and certainly not inside a CollectionChanged Event.
Used this in the oncollectionchanged and it works (WPF and MVVM example):
new System.Threading.Thread(t =>
{
Application.Current.Dispatcher.Invoke((Action)delegate
{
OnHoldMessages.Add(_selectedOnHoldMessage);
RaisePropertyChanged(propertyName: "OnHoldMessages");
});
}).Start();