Il n'y a pas beaucoup d'options pour un panneau d'enveloppement virtualisé pour une utilisation dans WPF. Pour une raison ou une autre, MS a décidé de ne pas expédier une dans la bibliothèque standard. P>
Si quelqu'un pouvait être si audacieux de fournir une réponse source de la foule (et une explication) au premier élément de travail du projet CodePlex suivant, je l'apprécierais grandement: P>
http://virtualwrappanel.codeplex.com/workitem/1 p>
Merci! P>
Résumé du problème: P>
J'ai récemment essayé d'utiliser le wrappanel virtualisé de ce projet et avez rencontré un bogue. p>
Étapes pour reproduire: p>
Le debug.assert échoue (debug.assert (enfant == _children [Childindex], "mauvais enfant a été généré");) Dans la mesure de la mesure, et une exécution continue entraîne une exception null dans la méthode de nettoyage [voir Capture d'écran ci-jointe] . p>
S'il vous plaît laissez-moi savoir si vous êtes capable de corriger cela. p>
merci, p>
ao p>
code: p>
http://virtualwrappanel.codeplex.com/sourcecontrol/list/changesets# p>
3 Réponses :
Tout d'abord, méfiez-vous en général, si vous retirez un objet d'une collection et que vous n'avez pas de référence, cet objet est mort au point de suppression. Ainsi, à la moindre appel refollantinalchildrange est illégal après la suppression, mais ce n'est pas le problème de base.
Deuxièmement, vous pourriez avoir une petite condition de course, même si ce n'est pas strictement multi-fileté. Avoir à vérifier (avec point d'arrêt) si ce gestionnaire d'événements réagit trop avec impatience - vous ne voulez pas que le gestionnaire d'événements fonctionne pendant que vous êtes toujours au milieu d'un retrait même s'il s'agit d'un seul élément. P>
Troisième, Vérifiez pour NULL après: p> et pour le premier essai change le code pour avoir une sortie gracieuse, ce qui signifie dans ce cas que GRACEFLEL continue - doit utiliser une boucle et des incréments dans La boucle pour pouvoir faire continue du tout. p> Vérifiez également les internometchildren WHNE que vous voyez que NULL pour voir si ce chemin d'accès donne le même résultat que vos _ enfants, des données internes, NULL dans le même endroit)) > En outre, postez le projet d'échantillon entièrement compilable qui donne la reproduction (en tant que fichier zip) quelque part - réduit les informations aléatoires et permet à la PPL de construire / courir et de voir. P> Parler d'hypothèses - chèque Quelle est votre "collection observable". Si vous retirez un article d'une collection, tout itérateur / énumérateur d'un état préalable de cette collection a le droit de lancer ou de donner des nulls forts> et dans une interface utilisateur qui tente d'être trop intelligente, ayant Un itérateur rassis peut se produire facilement. P> p>
La méthode OnitemSchanged doit bien gérer correctement les paramètres ARGS. S'il vous plaît voir cette Question pour plus d'informations. Copier le code de cette question, vous devrez mettre à jour suremschanged comme:
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) { base.OnItemsChanged(sender, args); _abstractPanel = null; ResetScrollInfo(); // ...ADD THIS... switch (args.Action) { case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Replace: RemoveInternalChildRange(args.Position.Index, args.ItemUICount); break; case NotifyCollectionChangedAction.Move: RemoveInternalChildRange(args.OldPosition.Index, args.ItemUICount); break; } }
Vous avez demandé une explication de ce qui se passe mal aussi bien que des instructions sur la manière de le réparer. Jusqu'à présent, personne n'a expliqué le problème. Je le ferai. P> Dans la liste de liste avec un virtualizingwrappanel Il existe cinq structures de données distinctes qui suivent des éléments de suivi, chacun de différentes manières: P> Lorsqu'un élément est retiré des élémentsSource, cette suppression doit être propagée via toutes les structures de données. Voici comment ça marche: p> Pour cette raison, la collection internalchildren est désynchronisée avec les quatre autres collections, ce qui a conduit aux erreurs expérimentées. P> Solution au problème strong> p> Pour résoudre le problème, ajoutez le code suivant n'importe où dans la méthode Onitemschanged de virtualisatricewrappanel: P> Ceci maintient la collection internalchildren en synchronisation avec les autres structures de données. p> Vous pouvez vous demander pourquoi il n'y a pas d'appels à insérer Nationinernalchild ou Addinernalchild dans le code ci-dessus, et surtout pourquoi la manutention Remplacer et déplacer ne nécessite pas que nous ajoutons d'ajouter un nouvel élément pendant OnitemSchanged. P> La clé pour comprendre cela est de la manière que l'élémentContainergénération fonctionne. P> Lorsque l'élémentContainerergenerator reçoit un éventuel éventuel Tout immédiatement: p> D'autre part, l'élémentContaingerernérateur apprend qu'un élément est ajouté, tout est généralement différé: p> Ainsi, tous les déménagements de la collection internalchildren (y compris ceux qui font partie d'un déplacement ou de remplacement) doivent être effectués à l'intérieur suremschanged, mais des ajouts peuvent (et doivent) être différés jusqu'à la prochaine mesure. P > p>
On dirait que Tom Goff a donné le code nécessaire pendant que je tapais ma réponse. Sa réponse est également correcte et est essentiellement la même chose que la mienne sans explication détaillée.
HI RAY - Nice résumé, vous avez eu mon vote. Un problème avec votre réponse est que la question n'est pas vraiment que la "collection interne de l'interruption est désynchronisée avec les quatre autres collections", mais je suis sûr que cela n'aide pas. La question sous-jacente est que les enfants réalisés ne sont pas «nettoyés». Si vous supprimez l'élément à l'index 10, l'élément de l'index 11 sera déplacé à l'index 10. Lorsque vous allez réaliser l'élément à l'index 10 (qui était auparavant à 11 heures), vous finirez par l'affirmation "incorrect enfant" a été généré ", étant donné que l'autre enfant n'a jamais été non réalisé.