RemoveAll为ObservableCollections?

我正在寻找Linq的方式(像RemoveAll方法列表),可以从我的ObservableCollection中删除选定的项目。

我太新,无法为自己创build扩展方法。 有没有什么办法从ObservableCollection中移除传递Lambdaexpression式的项目?

我不知道只能删除所选项目的方法。 但创build一个扩展方法是直接的:

public static class ExtensionMethods { public static int Remove<T>( this ObservableCollection<T> coll, Func<T, bool> condition) { var itemsToRemove = coll.Where(condition).ToList(); foreach (var itemToRemove in itemsToRemove) { coll.Remove(itemToRemove); } return itemsToRemove.Count; } } 

这将删除ObservableCollection中与条件匹配的所有项目。 你可以这样称呼它:

 var c = new ObservableCollection<SelectableItem>(); c.Remove(x => x.IsSelected); 

在Daniel Hilgarth的例子中,迭代迭代应该比创build一个临时集合更有效率。

 public static class ObservableCollectionExtensions { public static void RemoveAll<T>(this ObservableCollection<T> collection, Func<T, bool> condition) { for (int i = collection.Count - 1; i >= 0; i--) { if (condition(collection[i])) { collection.RemoveAt(i); } } } } 

这个单线程的实现呢?

 observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i)) 

– 编辑 –

对不起,你需要中间的ToList()强制前半部分进行评估,因为LINQ默认情况下是懒惰评估。

这里提出的每个使用例程逐个删除项目的解决scheme都有一个错误。 想象一下,你有很多可观察的物品,比如说10.000个物品。 然后你想删除符合条件的物品。

如果您使用Daniel Hilgarth解决scheme,请调用: Daniel Hilgarth c.Remove(x => x.IsSelected); 并且有例如3000个被移除的项目,build议的解决scheme将通知关于每个项目移除。 这是由于Remove(item)内部实现通知有关此更改的事实。 这将被删除过程中的3000个项目的每个要求。

所以,而不是我创buildObservableCollection的后代,并添加新的方法RemoveAll(predicate)

 [Serializable] public class ObservableCollectionExt<T> : ObservableCollection<T> { public void RemoveAll(Predicate<T> predicate) { CheckReentrancy(); List<T> itemsToRemove = Items.Where(x => predicate(x)).ToList(); itemsToRemove.ForEach(item => Items.Remove(item)); OnPropertyChanged(new PropertyChangedEventArgs("Count")); OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } 

有趣的是itemsToRemove.ForEach(item => Items.Remove(item)); 。 直接调用Items.Remove(item)将不会通知删除的项目。

而是在删除所需的项目后,通过调用立即通知更改:

 OnPropertyChanged(new PropertyChangedEventArgs("Count")); OnPropertyChanged(new PropertyChangedEventArgs("Item[]")); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 

没有办法将expression式传递给ObservableCollection来移除匹配的项目,就像通用列表一样。 ObservableCollection一次添加和删除一个项目。

您将不得不创build您自己的INotifyCollectionChanged实现,以便执行此操作,或者像您提到的那样创build一个扩展方法。

这是我的扩展方法解决scheme的版本,这只是接受的答案的一个小的变化,但有一个优点,返回的计数是基于确认从集合中删除项目:

 public static class ObservableCollectionExtensionMethods { /// <summary> /// Extends ObservableCollection adding a RemoveAll method to remove elements based on a boolean condition function /// </summary> /// <typeparam name="T">The type contained by the collection</typeparam> /// <param name="observableCollection">The ObservableCollection</param> /// <param name="condition">A function that evaluates to true for elements that should be removed</param> /// <returns>The number of elements removed</returns> public static int RemoveAll<T>(this ObservableCollection<T> observableCollection, Func<T, bool> condition) { // Find all elements satisfying the condition, ie that will be removed var toRemove = observableCollection .Where(condition) .ToList(); // Remove the elements from the original collection, using the Count method to iterate through the list, // incrementing the count whenever there's a successful removal return toRemove.Count(observableCollection.Remove); } }