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, so I seem to be limited to using the one event handler defined (CollectionChanged) to perform a .Remove() on the prohibited items. It's fine if the items exist for the short period between the event being raised and then handled; the items should just not persist in the collection. Calling .Remove() within the CollectionChanged event handler doesn't appear to be allowed. At runtime .NET throws an InvalidOperationException:
"Cannot change ObservableCollection during a CollectionChanged event."
Personally I think .NET should allow me to. If I create an infinite loop, it's my own darn fault.
The code I would like to use would look like:
myCollection.CollectionChanged += (sender, args) =>
{
if (args.Action == NotifyCollectionChangedAction.Remove)
return;
foreach (var itm in myCollection)
{
if (itm.name == "Fred")
myCollection.Remove(itm);
}
}
I'm not sure what options I have. Using a dispatcher doesn't seem to work. Triggering another event and placing the .Remove call in another handler is the only other option that comes to mind.
Check out Common Mistakes using Observable Collection.
Having said that, if you still want to go this route - you can spin a new Thread
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With