J'ai essayé d'utiliser à la fois un DataGrid personnalisé ainsi que celui d'origine dans WPF. J'ai essayé de les remplir manuellement ainsi que par le biais de liaisons. Dans les deux cas, ils sont lents.
J'ai un scénario où l'utilisateur clique sur un bouton et un DataGrid apparaît avec les données appropriées. Actuellement, je suis en mode preuve de concept et j'utilise uniquement des exemples de données. J'ai un DataSet avec une table qui contient 10 lignes.
Si je n'attache aucune donnée au DataGrid lorsque je clique sur le bouton que le DataGrid vide affiche à peu près instantanément, un utilisateur ne peut pas percevoir de retard. Dès que j'ajoute 10 lignes de données, pour 6 colonnes, le délai est d'environ 2 secondes, très sensible à l'utilisateur.
J'ai même essayé de remplir des données vides, juste pour faire apparaître une grille vide et c'est tout aussi lent.
for (int i = 0; i < 10; i++)
_dataGrid.Items.Add("");
Je mets une minuterie pour compter les ticks entre le moment où le bouton est cliqué et celui où tout le code est exécuté pour dessiner le DataGrid et il est d'environ 20 millisecondes, donc le code s'exécute très rapidement, mais sur l'écran se trouve le grand décalage . J'ai essayé un GridView et il s'affiche beaucoup plus rapidement à l'écran.
J'ai entendu divers rapports de dessin DataGrid lent avec des scénarios complexes et utilisant des milliers de lignes, mais c'est aussi simple que cela, 6 colonnes par 10 lignes remplies de données vides.
Pour l'affichage en lecture seule, GridView est-il une option tout aussi viable pour DataGrid?
Mettre à jour
Voici la création de mes colonnes.
DataGridTextColumn column = new DataGridTextColumn();
column.ColumnWidthChanged += new ColumnWidthChangedEventHandler(column_ColumnWidthChanged);
column.Header = entity.GetPropertyValue("ColumnLabel");
column.Binding = new Binding(entity.GetPropertyValue("Tag"));
column.Width = new DataGridLength(entity.GetPropertyDouble("DisplaySize"));
_dataGrid.Columns.Add(column);
C'est ainsi que je lie le DataSet avec 10 lignes.
_dataGrid.ItemsSource = ds.Tables[0].DefaultView;
_dataGrid.DataContext = ds.Tables[0];
Je ne sais pas ce que je peux faire différemment.
Avez-vous:
VirtualizingStackPanel.VirtualizationMode
pour une grille? sinon - essayez de régler.Encore un point, pourriez-vous lier une collection d'éléments entiers à la fois au lieu d'ajouter chaque élément dans la grille. Collection d'articles?
Un conseil général pour DataGrid
problèmes de performances: j'ai eu un problème avec le DataGrid dans lequel il a fallu littéralement quelques secondes pour actualiser après le redimensionnement d'une fenêtre, le tri des colonnes, etc. et j'ai verrouillé l'interface utilisateur de la fenêtre pendant ce temps ( 1000 lignes, 5 colonnes).
Il s'agissait d'un problème (bug?) Avec les calculs de dimensionnement WPF. Je l'avais dans une grille avec le RowDefinition
Height="Auto"
qui obligeait le système de rendu à recalculer la taille du DataGrid au moment de l'exécution en mesurant la taille de chaque colonne et ligne, probablement en remplissant toute la grille (si je comprends bien). Il est censé gérer cela intelligemment, mais dans ce cas, ce n'était pas le cas.
Une vérification rapide pour voir s'il s'agit d'un problème connexe consiste à définir les propriétés Height
et Width
du DataGrid à une taille fixe pendant la durée du test, puis réessayez d'exécuter. Si vos performances sont restaurées, un correctif permanent peut figurer parmi ces options:
MaxHeight
et MaxWidth
du DataGrid sur une valeur fixe supérieure à celle qu'il pourrait obtenir en utilisation normaleGrid
, DockPanel
, etc.)n blog que j'ai trouvé sur Google m'a donné une sorte de solution. Comme l'a dit l'auteur, j'ai désactivé GroupStyle et le problème de vitesse de rendu a été résolu. Mais j'avais besoin d'un regroupement. L'auteur a dit
VirtualizingPanel.IsVirtualizingWhenGrouping
est ajouté à .NET 4.5. Je l'ai donc mis à vrai. Le rendu est désormais rapide avec le regroupement. Le problème est que ... le défilement est saccadé. Pas saccadé inacceptable, mais saccadé notable. J'ai eu un problème similaire lorsque j'ai essayé de créer un TreeView avec plus de 2000 nœuds étendus. Sans virtualisation, le rendu était lent mais le défilement était fluide. Avec la virtualisation, le rendu était rapide mais le défilement était saccadé.
Pourquoi ne pouvons-nous pas avoir les deux ...
Dans mon cas, j'ai eu un problème avec DataGridCell ControlTemplate qui a ralenti le rendu.
Sachez que les vitesses de chargement relatives pour un grand ensemble de données sont très différentes pour l'utilisation de TextBlock (qui n'est pas du texte sélectionnable) ou TextBox en mode ReadOnly:
Temps de chargement 59 secondes:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox IsReadOnly="True" Text="{Binding Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Temps de chargement 21 secondes:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Temps de chargement 16 secondes:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBlock Text="{Binding}"></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Eh bien, en ajoutant un peu plus (je connais son sujet très ancien, mais ça aide quand même quelqu'un) ...
J'ai essayé
EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True"
pour DataGrid (AutoGenerateColumns="True"
) liaison à DataTable.DefaultView () et aucun effet sur la vitesse, c'était toujours horrible pour la vitesse ainsi que pour la navigation entre les lignes. Ensuite, j'ai trouvé une solution pour définir la hauteur et la largeur fixes de DataGrid. De plus, je mets aussi
RowHeight="23"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Cela fait que ma page se remplit très rapidement ... Au lieu de 2 min, il ne faut désormais plus que 10 à 12 secondes.
J'espère que cela aide quelqu'un.
Remarque: j'utilise .Net 4.5
Pour moi, c'était:
<Setter Property='ScrollViewer.CanContentScroll' Value='False' />
J'ai supprimé cela du style et le rendu est devenu rapide.
J'avais de gros problèmes avec 1000 lignes, 5 colonnes où le temps de rendu prenait 7 à 10 secondes, mais la solution trouvée à https://www.elegant-software.net/2014/05/performance-of -the-wpf-datagrid.html a fait que la grille se charge instantanément!
<DataGrid
EnableRowVirtualization="True"
EnableColumnVirtualization="True">
J'ai une Surface Pro 3 sur laquelle ma grille de données, avec environ 200 lignes et 10 colonnes, était vraiment lente à défiler, saccadée et hésitante.
Je pensais que c'était le réseau, mais c'était en fait la carte graphique qui ne pouvait pas suivre - attendez - un effet d'ombre portée sur la grille de données elle-même, même si l'arrière-plan du contrôle était réglé sur une couleur unie.
J'ai commenté l'effet et c'était 4-5 fois plus rapide.
J'espère que cela t'aides.
J'ai le même problème avec la grille de données liée, et je remarque que lors du premier chargement, il est rapide mais sur secand et ensuite il est lent. Donc, quand j'ajoute du code
DataGrid.ItemsSource = Nothing
Puis TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure
c'est devenu très RAPIDE