RemoveAll pour ObservableCollections?

Je cherche la méthode Linq (comme la méthode RemoveAll pour List) qui peut supprimer les éléments sélectionnés de mon ObservableCollection.

Je suis trop nouveau pour créer une méthode d’extension pour moi-même. Est-il possible de supprimer des éléments de ObservableCollection en passant une expression Lambda?

    Je ne suis pas au courant d’un moyen de supprimer uniquement les éléments sélectionnés. Mais créer une méthode d’extension est simple:

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

    Cela supprime tous les éléments de ObservableCollection qui correspondent à la condition. Vous pouvez l’appeler comme ça:

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

    Itérer en arrière devrait être plus efficace que de créer une collection temporaire comme dans l’exemple de Daniel Hilgarth.

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

    Que diriez-vous de cette mise en œuvre pour un one-liner?

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

    — Modifier —

    Désolé, oui, vous avez besoin d’une ToList () au milieu pour forcer le premier semestre à évaluer, car LINQ effectue une évaluation paresseuse par défaut.

    Chacune des solutions proposées ici qui utilise la routine pour supprimer un élément un par un a un défaut. Imaginez que vous ayez beaucoup d’éléments dans la collection observable, disons 10.000 articles. Ensuite, vous souhaitez supprimer les éléments qui répondent à certaines conditions.

    Si vous utilisez la solution de Daniel Hilgarth et appelez: c.Remove(x => x.IsSelected); et il y a par exemple 3000 articles à supprimer, la solution proposée vous informera de la suppression de chaque article. Cela est dû au fait que l’implémentation interne de Remove(item) notifie cette modification. Et ce sera appelé pour chacun des 3000 éléments dans le processus de suppression.

    Donc, au lieu de cela, j’ai créé un descendant de ObservableCollection et ajouté une nouvelle méthode RemoveAll(predicate)

     [Serializable] public class ObservableCollectionExt : ObservableCollection { public void RemoveAll(Predicate predicate) { CheckReentrancy(); List 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)); } } 

    La ligne intéressante est itemsToRemove.ForEach(item => Items.Remove(item)); . Appeler directement Items.Remove(item) ne vous informera pas de l’élément supprimé.

    Au lieu de supprimer les éléments requirejs, les modifications sont notifiées immédiatement par des appels:

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

    Il est impossible de transmettre une expression à ObservableCollection pour supprimer des éléments correspondants, de la même manière qu’une liste générique. ObservableCollection ajoute et supprime un élément à la fois.

    Pour ce faire, vous devrez créer votre propre implémentation d’INotifyCollectionChanged ou créer une méthode d’extension.

    Ceci est ma version d’une solution de méthode d’extension, qui ne représente qu’une légère variation de la réponse acceptée, mais qui présente l’avantage que le décompte renvoyé est basé sur la suppression confirmée de l’élément de la collection:

     public static class ObservableCollectionExtensionMethods { ///  /// Extends ObservableCollection adding a RemoveAll method to remove elements based on a boolean condition function ///  /// The type contained by the collection /// The ObservableCollection /// A function that evaluates to true for elements that should be removed /// The number of elements removed public static int RemoveAll(this ObservableCollection observableCollection, Func 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); } }