WPF Toolkit DataGrid défilement des problèmes de performance - pourquoi?
J'ai un problème de performance avec l' (WPF Toolkit) DataGrid. Il contient environ 1.000 lignes (seulement huit colonnes) et le défilement est horriblement lent et lag. Aussi la charge initiale de la Fenêtre contenant la grille de 5 à 10 secondes.
J'ai fait quelques recherches (à l'aide de google et StackOverflow), mais ne pouvait pas trouver quelque chose en plus de l'avis de tourner sur l'INTERFACE utilisateur de la virtualisation. Mais même après explicitement permettant le défilement continue à être affreusement lent.
Mon DataGrid est lié à un ICollectionView /objet collectionviewsource. Il est défini dans le code XAML de cette façon (les colonnes sont définis de manière explicite, pas de génération automatique):
<tk:DataGrid x:Name="dataGrid"
ItemsSource="{Binding Path=Bookings}"
AutoGenerateColumns="False"
Grid.Row="1"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
...
</tk:DataGrid>
Le DataContext pour l'ensemble de la Fenêtre est définie à une instance de la classe contenant la ICollectionView le contrôle DataGrid est lié à.
Chaque blog ou un post sur un forum j'ai trouvé faisait l'éloge de la grille de données de performance, donc je suis bien évidemment de faire quelque chose de grave. Depuis que je suis tout à fait nouveau pour WPF en général et en particulier pour le contrôle DataGrid, je n'ai pas la moindre idée de la manière de l'améliorer. Quelqu'avez quelques conseils pour moi? Quelle est votre expérience avec le composant DataGrid? Ce que je fais mal?
Edit: Juste suivi cette de la question des conseils pour définir la Largeur de toutes les colonnes de "Auto". Qui n'a pas changer les mauvaises performances de défilement. Aussi, je ne suis pas en utilisant DataGridTemplateColumns (juste quelques DataGridTextColumns et deux DataGridComboBoxColumns).
Edit2: j'ai utilisé Snoop regarder mon application. Ce que je vois suggère que la virtualisation est en effet à travailler (seulement 19 lignes, et non d'un millier). Mais chaque ligne contient 52 éléments, de sorte que ceux d'ajouter jusqu'à plus d'un millier d'éléments. Peut-être le problème?
Merci beaucoup!
- J'ai mis à jour ma réponse avec un moyen rapide de vérifier si la virtualisation est de travailler il serait bien si vous pouviez exclure que ce n'est pas le problème.
Vous devez vous connecter pour publier un commentaire.
La grille de données a une propriété Attachée, ScrollViewer.CanContentScroll, qui gère ce problème. Pour obtenir le défilement régulier, vous aurez besoin de le mettre à Faux.
ScrollVIewer.CanContentScroll
àfalse
même aidé beaucoup dans .NET 4.5 - bien que cela devrait déjà être améliorée en ce qui concerne les performances. J'ai toujours eu des problèmes avec le défilement ~1000 articles, maisCanContentScroll
il fixe.ScrollViewer.CanContentScroll
est fixé àfalse
... C'est pourquoi le défilement est plus rapide: les articles n'ont pas besoin d'être créé à la volée si la virtualisation est éteint.Après enfin à prendre le temps de construire ma demande par rapport à une version à jour de WPF le problème de défilement semble complètement disparu. Donc, si quelqu'un utilise encore la version toolkit de la grille de données juste "mettre à jour" pour la version incluse dans le cadre et vous devriez être bien.
Je suis à l'aide .NET 4.0 et encore obtenir le défilement problème de performance. Ce que j'ai fait est - désactivé virtualisation. J'ai mis EnableRowVirtualization "faux" dans la grille de données. Cela a considérablement amélioré le défilement de la performance.
Je suggère de ne pas supposer que ce qui est offert par de WPF est utile dans toutes les situations.
Ce conteneur ne votre datagrid vivre? Par exemple - si vous le mettez dans un scrollviewer, la grille de données va grandir pour afficher chaque ligne, donc la désactivation de la virtualisation (et le scrollviewer va faire apparaître normal, tout ce qui se passe). Assurez-vous que la grille de taille est bornée.
Il n'a vraiment sonner comme un virtalization chose, si cet avis ne fonctionne pas exécuter votre application par le biais d'un générateur de profils pour s'assurer de la virtualisation qui se passe.
Edit: Voici un exemple d'utilisation de snoop (ou de la mole, je suppose) de voir rapidement si la virtualisation est de travail.
http://blogs.msdn.com/jgoldb/archive/2008/03/25/quick-tips-to-improve-wpf-app-memory-footprint.aspx
Vous pourriez essayer d'ajouter les éléments un par un (ou ligne par ligne) dans la grille de données et mise à jour le thread d'INTERFACE utilisateur après chaque addition.
De cette façon, l'utilisateur voit le chargement de prendre place et il ne semble pas que l'application est à ne rien faire.
Voir ici une description plus détaillée de cette méthode
Aussi loin que le début du chargement va, je l'ai trouvé nécessaire d'étendre l'API publique pour améliorer de façon spectaculaire grand nombre de colonne de chargement - nous parlons minutes à moins d'une seconde. Cela dit, j'ai le même problème avec les performances de défilement, même 500+ colonnes est vraiment lent pour faire défiler.
Réglage des colonnes à l'intérieur de mon dérivés datagrid:
Correctifs pour DataGridColumnCollection:
J'ai trouvé que le fait d'avoir la largeur d'une colonne définie à
Auto
(par défaut!) peut introduire substantielle de défilement verticale lag quand il y a beaucoup de cellules. Commutation de largeur fixe a beaucoup aidé dans mon cas, même si on est encore détectable lag quand il y a beaucoup de colonnes.Vous pouvez définir
CanUserResizeColumns="True"
sur la grille, si vous êtes inquiet les utilisateurs ne seront pas comme les largeurs que vous sélectionnez.