Ich habe das tatsächlich gelöst, aber ich poste es für die Nachwelt.
Ich hatte ein sehr merkwürdiges Problem mit DataGridView auf meinem Dual-Monitor-System. Das Problem äußert sich in einem EXTREM langsamen Repaint des Steuerelements ( wie 30 Sekunden für ein vollständiges Repaint ), jedoch nur, wenn es sich auf einem meiner Bildschirme befindet. Auf der anderen Seite ist die Repaint-Geschwindigkeit in Ordnung.
Ich habe einen Nvidia 8800 GT mit den neuesten Nicht-Beta-Treibern (175. etwas). Ist es ein Treiberfehler? Ich werde das in der Luft lassen, da ich mit dieser speziellen Konfiguration leben muss. (Bei ATI-Karten ist dies jedoch nicht der Fall ...)
Die Malgeschwindigkeit hat nichts mit dem Zelleninhalt zu tun, und das benutzerdefinierte Zeichnen verbessert die Leistung überhaupt nicht - selbst wenn nur ein festes Rechteck gemalt wird.
Ich finde später heraus, dass das Platzieren eines ElementHost (aus dem System.Windows.Forms.Integration-Namespace) im Formular das Problem behebt. Es muss nicht durcheinander gebracht werden; Es muss nur ein untergeordnetes Element der Form sein, in der sich auch DataGridView befindet. Die Größe kann auf (0, 0) geändert werden, solange die Visible- Eigenschaft wahr ist.
Ich möchte meiner Anwendung die .NET 3 / 3.5-Abhängigkeit nicht explizit hinzufügen. Ich mache eine Methode, um dieses Steuerelement zur Laufzeit (wenn es kann) unter Verwendung von Reflektion zu erstellen. Es funktioniert, und zumindest schlägt es auf Computern, die nicht über die erforderliche Bibliothek verfügen, ordnungsgemäß fehl - es wird einfach wieder langsam.
Mit dieser Methode kann ich auch Korrekturen anwenden, während die App ausgeführt wird, sodass ich leichter sehen kann, was die WPF-Bibliotheken in meinem Formular ändern (mit Spy ++).
Nach vielen Versuchen und Irrtümern stelle ich fest, dass das Aktivieren der doppelten Pufferung auf dem Steuerelement selbst (im Gegensatz zum Formular) das Problem behebt!
Sie müssen also nur eine benutzerdefinierte Klasse erstellen, die auf DataGridView basiert, damit Sie deren DoubleBuffering aktivieren können. Das ist es!
class CustomDataGridView: DataGridView
{
public CustomDataGridView()
{
DoubleBuffered = true;
}
}
Solange alle meine Instanzen des Rasters diese benutzerdefinierte Version verwenden, ist alles in Ordnung. Wenn ich jemals auf eine dadurch verursachte Situation stoße, in der ich die Unterklassenlösung nicht verwenden kann (wenn ich den Code nicht habe), könnte ich versuchen, dieses Steuerelement in das Formular einzufügen :) ( obwohl ich ' Es ist wahrscheinlicher, dass Sie versuchen, die DoubleBuffered-Eigenschaft mithilfe von Reflection von außen zu aktivieren, um die Abhängigkeit erneut zu vermeiden .
Es ist traurig, dass so eine trivial einfache Sache so viel Zeit in Anspruch genommen hat ...
quelle
Antworten:
Sie müssen nur eine benutzerdefinierte Klasse erstellen, die auf DataGridView basiert, damit Sie das DoubleBuffering aktivieren können. Das ist es!
Solange alle meine Instanzen des Rasters diese benutzerdefinierte Version verwenden, ist alles in Ordnung. Wenn ich jemals auf eine dadurch verursachte Situation stoße, in der ich die Unterklassenlösung nicht verwenden kann (wenn ich den Code nicht habe), könnte ich versuchen, dieses Steuerelement in das Formular einzufügen :) (obwohl ich ' Es ist wahrscheinlicher, dass Sie versuchen, die DoubleBuffered-Eigenschaft mithilfe von Reflection von außen einzuschalten, um die Abhängigkeit erneut zu vermeiden.
Es ist traurig, dass so eine trivial einfache Sache so viel Zeit in Anspruch genommen hat ...
Hinweis: Machen Sie die Antwort zu einer Antwort, damit die Frage als beantwortet markiert werden kann
quelle
Hier ist ein Code, der die Eigenschaft mithilfe von Reflection festlegt, ohne Unterklassen, wie von Benoit vorgeschlagen.
quelle
Control
Klasse.public static void ToggleDoubleBuffered(this Control control, bool isDoubleBuffered)
.Für Leute, die suchen, wie es in VB.NET geht, ist hier der Code:
quelle
Wenn ich zu früheren Beiträgen hinzufüge, verwende ich dies für Windows Forms-Anwendungen für DataGridView-Komponenten, um sie schnell zu machen. Der Code für die Klasse DrawingControl ist unten.
Rufen Sie DrawingControl.SetDoubleBuffered (Steuerelement) nach InitializeComponent () im Konstruktor auf.
Rufen Sie DrawingControl.SuspendDrawing (Steuerelement) auf, bevor Sie Big Data-Updates durchführen.
Rufen Sie DrawingControl.ResumeDrawing (Steuerelement) auf, nachdem Sie Big Data-Updates durchgeführt haben.
Diese letzten beiden werden am besten mit einem try / finally-Block ausgeführt. (oder noch besser die Klasse umschreiben als
IDisposable
undSuspendDrawing()
den Konstruktor undResumeDrawing()
in aufrufenDispose()
.)quelle
Die Antwort darauf hat auch bei mir funktioniert. Ich dachte, ich würde eine Verfeinerung hinzufügen, die meiner Meinung nach Standard für jeden sein sollte, der die Lösung implementiert.
Die Lösung funktioniert gut, außer wenn die Benutzeroberfläche als Clientsitzung unter Remotedesktop ausgeführt wird, insbesondere wenn die verfügbare Netzwerkbandbreite gering ist. In einem solchen Fall kann die Leistung durch die Verwendung von Doppelpufferung verschlechtert werden. Daher schlage ich Folgendes als vollständigere Antwort vor:
Weitere Informationen finden Sie unter Erkennen der Remotedesktopverbindung
quelle
Ich habe eine Lösung für das Problem gefunden. Wechseln Sie in den erweiterten Anzeigeeigenschaften zur Registerkarte Fehlerbehebung, und überprüfen Sie den Schieberegler für die Hardwarebeschleunigung. Als ich meinen neuen Firmen-PC von der IT bekam, war er auf einen Tick von voll eingestellt und ich hatte keine Probleme mit Datagrids. Nachdem ich den Grafikkartentreiber aktualisiert und auf "Voll" gesetzt hatte, wurde das Malen der Datagrid-Steuerelemente sehr langsam. Also habe ich es wieder auf den Stand zurückgesetzt und das Problem ist behoben.
Hoffe, dieser Trick funktioniert auch für Sie.
quelle
Nur um hinzuzufügen, was wir getan haben, um dieses Problem zu beheben: Wir haben ein Upgrade auf die neuesten Nvidia-Treiber durchgeführt, um das Problem zu beheben. Es musste kein Code neu geschrieben werden.
Der Vollständigkeit halber handelte es sich bei der Karte um eine Nvidia Quadro NVS 290 mit Treibern vom März 2008 (Version 169). Durch das Upgrade auf die neueste Version (Version 182 vom Februar 2009) wurden die Malereignisse für alle meine Steuerelemente, insbesondere für DataGridView, erheblich verbessert.
Dieses Problem wurde auf keiner ATI-Karte festgestellt (wo die Entwicklung stattfindet).
quelle
Beste!:
quelle
Bei der Verwendung von .NET 3.0 und DataGridView auf einem System mit zwei Monitoren ist ein ähnliches Problem aufgetreten.
Unsere Anwendung würde das Raster mit einem grauen Hintergrund anzeigen, was darauf hinweist, dass die Zellen nicht geändert werden konnten. Bei Auswahl einer Schaltfläche "Einstellungen ändern" ändert das Programm die Hintergrundfarbe der weißen Zellen, um dem Benutzer anzuzeigen, dass der Zellentext geändert werden kann. Eine Schaltfläche "Abbrechen" würde die Hintergrundfarbe der oben genannten Zellen wieder in Grau ändern.
Wenn sich die Hintergrundfarbe ändert, flackert es, ein kurzer Eindruck eines Rasters mit Standardgröße mit der gleichen Anzahl von Zeilen und Spalten. Dieses Problem würde nur auf dem primären Monitor (niemals auf dem sekundären) und nicht auf einem einzelnen Monitorsystem auftreten.
Die doppelte Pufferung der Steuerung anhand des obigen Beispiels löste unser Problem. Wir haben Ihre Hilfe sehr geschätzt.
quelle