ObservableCollection: appel de OnCollectionChanged avec plusieurs nouveaux éléments
veuillez noter que je suis en train d'utiliser NotifyCollectionChangedAction.Ajouter une action à la place de .Réinitialiser. ce dernier fonctionne, mais il n'est pas très efficace avec de grandes collections.
donc je sous-classé ObservableCollection:
public class SuspendableObservableCollection<T> : ObservableCollection<T>
pour une raison quelconque, ce code:
private List<T> _cachedItems;
...
public void FlushCache() {
if (_cachedItems.Count > 0) {
foreach (var item in _cachedItems)
Items.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, (IList<T>)_cachedItems));
}
}
est à jeter
Une collection Ajouter un événement fait référence à un élément qui n'appartient pas à la collection
ce qui semble être un bogue dans la BCL ?
Je peux passer et voir avant de faire appel à OnCollectionChanged que de nouveaux éléments sont ajoutés à cela.Les éléments
WOW
juste fait une stupéfiante découverte. Aucune de ces approches n'a fonctionné pour moi (chasse d'eau, addrange), parce que l'erreur semble être déclenché UNIQUEMENT si cette collection est lié à mon Listview!!
TestObservableCollection<Trade> testCollection = new TestObservableCollection<Trade>();
List<Trade> testTrades = new List<Trade>();
for (int i = 0; i < 200000; i++)
testTrades.Add(t);
testCollection.AddRange(testTrades); //no problems here..
_trades.AddRange(testTrades); //this one is bound to ListView .. BOOOM!!!
En conclusion, ObservableCollection prend en charge l'ajout incrémental de listes, mais une ListView qui ne fonctionne pas. Andyp trouvé une solution de contournement pour le faire fonctionner avec CollectionView ci-dessous, mais depuis .Refresh() est appelée, ce qui n'est pas différent que de simplement appeler OnCollectionChanged( .Remise à zéro )..
source d'informationauteur Sonic Soul
Vous devez vous connecter pour publier un commentaire.
vous pouvez mettre en œuvre AddRange() pour l'ObservableCollection comme cela, comme le montre ici:
Mise à JOUR: Après la liaison de zone de liste, j'ai vu une exception InvalidOperationException trop (même message que vous avez été voir). Selon cette l'article c'est parce que CollectionView ne prend pas en charge la gamme de mesures. Heureusement, l'article fournit également une solution (bien qu'il se sent un peu "hack-ish").
Mise à JOUR 2: Ajout d'un correctif qui soulève le substituée événement CollectionChanged dans le substituée la mise en œuvre de OnCollectionChanged().
Merci pour l'inspiration AndyP. J'ai eu quelques problèmes avec votre mise en œuvre, telles que l'utilisation de CollectionView au lieu de ICollectionView dans le test, ainsi que manuellement appeler "Reset" sur les éléments. Les éléments qui héritent de CollectionView peut effectivement faire face à ces arguments, en plus de manières que de l'appeler ".Reset()", il est donc préférable de toujours le feu de leurs maîtres, juste avec de l'Action=Reset args qu'ils ont besoin au lieu de l'amélioration de l'événement args qui comprennent la liste des articles a changé. Ci-dessous mon (très similaires) la mise en œuvre.
Après plusieurs itérations, nous avons terminé avec cette version de
ObservableRangeCollection
etReadOnlyObservableRangeCollection
qui est basé sur le code de la accepté de répondre, et dont nous n'avons pas eu à modifier dans les 6 derniers mois:Essentiellement, nous avons remplacé toutes les occurrences de
ObservableCollection
dans notre app parObservableRangeCollection
et il fonctionne comme un charme.Je crois que vous avez besoin pour le convertir en une
IList
:base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, (IList)_cachedItems));