Chacune des solutions proposées ici, qui utilise une routine pour retirer les articles un par un, présente un défaut. Imaginez que vous avez beaucoup d'éléments dans une collection observable, disons 10.000 éléments. Vous souhaitez alors supprimer les éléments qui remplissent certaines conditions.
Si vous utilisez solution de Daniel Hilgarth et appeler : c.Remove(x => x.IsSelected);
et qu'il y a par exemple 3000 éléments à supprimer, la solution proposée notifiera la suppression de chaque élément. Ceci est dû au fait que l'implémentation interne de Remove(item)
notifier ce changement. Et ceci sera appelé pour chacun des 3000 éléments du processus de suppression.
Au lieu de cela, j'ai créé un descendant de ObservableCollection et ajouté une nouvelle méthode 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));
}
}
La ligne intéressante est itemsToRemove.ForEach(item => Items.Remove(item));
. Appeler directement Items.Remove(item)
ne notifiera pas le retrait de l'article.
Au lieu de cela, après avoir retiré les éléments requis, les changements sont notifiés immédiatement par des appels :
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
0 votes
Related stackoverflow.com/questions/11688865/