Kürzlich habe ich einige Optimierungen am Code vorgenommen. Nach dem Test ist der Effekt in Ordnung, aber ich habe festgestellt, dass die Schnittstelle flackert, insbesondere das TreeView-Steuerelement, die Sprache ist C# und die IDE ist VS2005. Nachdem ich einige Informationen konsultiert und einige grundlegende Techniken angewendet hatte (z. B. die Aktivierung der Doppelpufferung), stellte ich fest, dass dies keine Wirkung hatte.
Deshalb habe ich das PRfiler-Tool verwendet, um herauszufinden, dass der Engpass im EndUpdate-Vorgang liegt, nachdem die Schnittstelle jedes Mal aktualisiert wurde (dies wird verwendet, um die Anzahl der Schnittstellenaktualisierungen zu reduzieren, ist hier jedoch nicht ideal, da das Steuerelement viele Elemente enthält). Ich vermute, dass jedes Mal, wenn es aktualisiert wird, die unterste Ebene von .Net jedes Grundelement aktualisiert und neu gezeichnet wird, sodass die Geschwindigkeit langsam ist und ein Flackern verursacht. Wenn dies jedoch der Fall ist, sollte die Verwendung von Doppelpufferung bessere Ergebnisse liefern. Als ich mir den Code noch einmal ansah, stellte ich fest, dass die Aktualisierungsaktion möglicherweise zu häufig erfolgt. Daher habe ich die Geschwindigkeit verringert und die Geschwindigkeit verbessert, aber es funktionierte immer noch nicht.
Suchen Sie weiter online und finden Sie schließlich eine Lösung, die besser geeignet ist. Es stellt sich heraus, dass das zugrunde liegende Neuzeichnen jedes Mal die Leinwand löscht und dann alles neu zeichnet. Dies ist die Hauptursache für das Flackern. Daher ist die Funktion zum Senden von Nachrichten überlastet und diese Nachricht ist deaktiviert. Der Code lautet wie folgt:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) // Löschen von Hintergrundmeldungen deaktivieren
zurückkehren;
base.WndProc(ref m);
}
Erfolg!
Hinweis: Doppelte Pufferung ist immer noch nützlich, wenn Aktualisierungen nicht sehr häufig sind und das Steuerelement nicht zu viele Elemente enthält. Sobald zu viele Elemente vorhanden sind, dauert jede Aktualisierung lange. Auch wenn doppelte Pufferung verwendet wird, kann das Flackerproblem nicht gelöst werden. Persönlich denke ich, dass die ideale Methode darin besteht, Hintergrundnachrichten zu deaktivieren und am Ende zu löschen.
Anhang: Einige Aufzeichnungen über Versuche und Misserfolge
1) Verwenden Sie setStyle
Im Internet heißt es, dass die setStyle-Funktion zum Festlegen der Parameter des Steuerelements verwendet wird, insbesondere:
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
Der letztere dieser drei Optionsparameter hängt vom ersteren ab und muss nebeneinander vorhanden sein, andernfalls ist er ungültig. Und diese Funktion selbst ist geschützt, Sie müssen also zunächst ein bestimmtes Steuerelement erben, bevor Sie sie verwenden können.
Dieses Ziel steht im Einklang mit der vorherigen korrekten Lösung, die ebenfalls das Löschen des Hintergrunds deaktiviert und die doppelte Pufferung aktiviert, aber die Benutzerzeichnungsoption erfordert und das gesamte Zeichnen durch den Benutzer erfolgt. Dies erfordert, dass Sie die gesamte Zeichnung der Steuerelemente selbst implementieren, was ziemlich mühsam ist. Diese Methode ist also nicht völlig undurchführbar, erfordert jedoch zusätzliche Arbeit und wird nicht empfohlen. Ich habe es auch nicht benutzt.
2) Verwenden Sie BeginUpdate und EndUpdate
Dieses Operationspaar hat eine bessere Wirkung in Szenarien, in denen Batch-Operationen zum Aktualisieren von Steuerelementen erforderlich sind, z. B. das stapelweise Hinzufügen einer großen Anzahl von Knoten während der Initialisierung. Der Nachteil besteht darin, dass es nicht sofort aktualisiert werden kann. Daher eignet es sich nicht für Situationen, in denen Knoten häufig aktualisiert werden und sofort in der Schnittstelle angezeigt werden sollen. Wenn Sie es verwenden und die klare Benutzeroberflächenmeldung nicht deaktivieren, scheint das Steuerelement zu flackern, hat hauptsächlich einen weißen Hintergrund und der Inhalt ist fast unsichtbar (abhängig von der Komplexität des Videos). Da die Schnittstellenaktualisierungen bei EndUpdate abgeschlossen sind, führen zu viele Vorgänge dazu, dass EndUpdate für längere Zeit blockiert wird und die Schnittstelle zuerst gelöscht und später aktualisiert wird, was dazu führt, dass die Schnittstelle für lange Zeit leer erscheint.
3) Verwenden Sie die Option ControlStyles.EnableNotifyMessage
Die Wirkung dieser Option stimmt auch mit der richtigen Lösung überein. Die Verwendung ist:
SetStyle(ControlStyles.EnableNotifyMessage, true);
protected override void onNotifyMessage(Message m)
{
//Hier Filternachrichtencode schreiben
}
Das eigentliche Experiment zeigte jedoch keine Wirkung, ich weiß nicht warum, und ich habe es nicht im Detail untersucht.
-