2008-09-15 9 views
7

Dans mon application, j'ai un contrôle DataGridView qui affiche des données pour l'objet sélectionné. Lorsque je sélectionne un objet différent (dans une liste déroulante ci-dessus), j'ai besoin de mettre à jour la grille. Malheureusement, différents objets ont des données complètement différentes, même des colonnes différentes. Je dois donc effacer toutes les données et colonnes existantes, créer de nouvelles colonnes et ajouter toutes les lignes. Quand cela est fait, le contrôle entier scintille horriblement et cela prend des âges. Existe-t-il un moyen générique d'obtenir le contrôle dans un état de mise à jour afin qu'il ne se repeigne pas, puis le repeindre après avoir terminé toutes les mises à jour?Scintillement lors des mises à jour de contrôles dans WinForms (par exemple DataGridView)

Il est certainement possible avec TreeViews:

myTreeView.BeginUpdate(); 
try 
{ 
    //do the updates 
} 
finally 
{ 
    myTreeView.EndUpdate(); 
} 

est-il un moyen générique de le faire avec d'autres contrôles, DataGridView en particulier? MISE À JOUR: Désolé, je ne suis pas sûr d'avoir été assez clair. Je vois la « vacillante », car après le contrôle unique du contrôle se repeint à l'écran, de sorte que vous pouvez voir la barre de défilement rétrécissement, etc.

+0

Ajoutez ceci dans votre DataGridView DoubleBuffered (true); –

Répondre

7

Plutôt que d'ajouter les lignes de la grille de données une à la fois, utilisez la méthode DataGridView.Rows.AddRange pour ajouter toutes les lignes à la fois . Cela devrait seulement mettre à jour l'affichage une fois. Il y a aussi un DataGridView.Columns.AddRange pour faire la même chose pour les colonnes.

+0

A bientôt, cela semble le meilleur que vous pouvez obtenir avec DataGridView – Grzenio

1

On dirait que vous voulez une double mémoire tampon:

http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

Bien que cela soit principalement utilisé pour les contrôles individuels, vous pouvez l'implémenter dans votre contrôle Windows Forms ou Form.

+2

J'ai essayé le double-buffering, mais ça n'a pas beaucoup aidé. Je pense que le problème est qu'il essaie de repeindre après chaque ligne que j'ajoute, de sorte qu'il finit par mettre à jour les premières lignes plusieurs fois. – Grzenio

1

Malheureusement, je pense que cela pourrait bien être un sous-produit du framework .net. Je ressens un scintillement similaire, mais avec des contrôles personnalisés. Une grande partie du matériel de référence que j'ai lu l'indique, à côté du fait que la méthode du double tampon n'a pas réussi à supprimer tout scintillement pour moi.

6

tampon double ne sera pas utile ici puisque que seuls les tampons doubles peinture des opérations, le vacillement l'OP voit est le résultat de plusieurs opérations de peinture:

  • Contenu de la commande claires -> repeindre
  • colonnes claires -> repeindre
  • POPULATE nouvelles colonnes -> repeindre
  • Ajouter des lignes -> repeindre

donc c'est quatre repaints pour mettre à jour le contrôle, d'où le scintillement. Malheureusement, tous les contrôles standard n'ont pas le BeginUpdate/EndUpdate qui supprimerait tous les appels de repaint jusqu'à ce que le EndUpdate soit appelé. Voici ce que vous pouvez faire:

  1. Avoir un contrôle différent pour chaque ensemble de données et Afficher/Masquer les contrôles,
  2. Retirez le contrôle de son parent, mise à jour, puis ajouter le contrôle à nouveau,
  3. Écrivez votre propre contrôle.

Les options 1 et 2 clignotent encore un peu.

Sur le programme .Net GUI sur lequel je travaille, j'ai créé un ensemble de contrôles personnalisés qui ont éliminé tout scintillement.

+0

Oui, je suis à peu près sûr que c'est exactement le problème. Et parce que je dois ajouter> 50 lignes, vous pouvez voir comment la grille se développe. Lorsque vous avez créé vos contrôles, vous avez étendu la vue de grille de données existante ou en avez créé une nouvelle à partir de rien. – Grzenio

+0

Je les ai écrits à partir de zéro, dérivé de UserControl et ils sont tous très spécifiques à l'application. – Skizz

8

Le contrôle .NET prend en charge les méthodes SuspendLayout et ResumeLayout. Choisissez le contrôle parent approprié (c.-à-d.le contrôle qui héberge les contrôles que vous souhaitez remplir) et faire quelque chose comme ce qui suit:

this.SuspendLayout(); 

// Do something interesting. 

this.ResumeLayout(); 
+2

Ouais, je l'ai essayé, mais ça ne marche pas :( – Grzenio

2

Cela a fonctionné pour moi.

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

Fondamentalement, il consiste à déduire du contrôle souhaité et le réglage des styles suivants.

SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true); 
7

Les gens semblent oublier une solution simple pour cela:

Object.Visible = false; 

//do update work 

Object.Visible = true; 

Je sais que cela semble bizarre, mais cela fonctionne. Lorsque l'objet n'est pas visible, il ne se redessine pas. Vous devez cependant effectuer la mise à jour begin et end.

+0

Cela devrait avoir beaucoup plus de points, m'aurait sauvé beaucoup de temps. travailler pour mon cas d'utilisation mais c'était parfait Merci! –

0

Vous pouvez également essayer cela, son travail.

public static void DoubleBuffered(Control formControl, bool setting) 
{ 
    Type conType = formControl.GetType(); 
    PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); 
    pi.SetValue(formControl, setting, null); 
} 
Questions connexes