Flackern beim Laden von UserControls verhindern

10/03/2009 - 08:18 von Thomas Meutzner | Report spam
Hallo,
ich habe eine WinForms Anwendung mit C#2008 und unter Verwendung des
Framework 3.5 erstellt.
Diese Anwendung besitzt links einen Navigationsbereich und rechts der
Arbeitsbereich, der je nach angeklickten Menüpunkt unterschiedliche
Daten darstellt. In der Regel ist der Arbeitsbereich in einen
Tabellenansicht (oben) und eine Detailansicht (unten, dient als
Vorschau) aufgeteilt. Zum Einsatz kommen neben den WinForms Controls
auch die Janus WinForms Controls.

Die Formulare für den Arbeitsbereich habe ich als UserControls
erstellt. Diese UserControls füllen den rechten Bereich komplett aus
(Dock=Fill). Im Vorschaubereich sind viele Controls enthalten, die als
Hintergrundfarbe Transparent verwenden und die sich teilweise in
Groupboxen befinden. In den Load-Ereignissen werden die entsprechenden
Daten aus der Datenbank geholt und an die Elemente gebunden.
Alle UserControls für den Arbeitsbereich sind von einem
"Haupt-UserControl" abgeleitet, welches verschiedene Eigenschaften und
Methoden zur Verfügung stellt, die ich überschreiben kann. Das
ansteuern und Anzeigen der UserControls aus dem Hauptprogramm erfolgt
so:
- Prüfung welches Control geladen werden soll
- Bildung einer neuen Instanz des Controls
- Unsichtbar setzen des Controls
- Setzen der verschiedenen Eigenschaften (z.B. DataSource, aktueller
Benutzer etc.)
- Einbindung in den rechten Bereich des Hautprogrammes
- Anzeige des Controls

Ich habe das Problem, dass man beim Laden der UserControls ein
Flackern sieht. Um dies zu verhindern habe ich bei jedem UserControl
im Konstruktor SetStyle gesetzt:
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);

Im Konstruktor und im Load-Ereignis wurden außerdem vor und nach den
aufgerufenen Methoden this.SuspendLayout() und this.ResumeLayout()
implementiert.
Dies führte zu keiner sichtbaren Reduktion des Flackerns. Auch das
setzen von Visible=false nach dem Instanzieren des Controls brachte
keine Besserung.
Danach habe ich in den Quellcode des Controls CreateParams
überschrieben.
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return result;
}
}

Jetzt flackert es weniger, aber dafür habe ich zwei neue
Erscheinungen:
1. Bei einigen verschachtelten Controls die Hintergrundfarbe nicht
mehr transparent angezeigt, sondern diese ist weiß.
2. Wenn ich einen Dialog über meine Anwendung lege und diesen mit der
Maus verschiebe, erhalte ich Schlieren auf dem Bildschirm.

Wie geht Ihr bei komplexen Layouts vor, um das Flackern zu
unterbinden?
Vielen Dank.
Thomas Meutzner
 

Lesen sie die antworten

#1 Carsten Unterberg
10/03/2009 - 08:34 | Warnen spam
Hallo Thomas,

"Thomas Meutzner" schrieb im Newsbeitrag
news:
Hallo,
ich habe eine WinForms Anwendung mit C#2008 und unter Verwendung des
Framework 3.5 erstellt.
Diese Anwendung besitzt links einen Navigationsbereich und rechts der
Arbeitsbereich, der je nach angeklickten Menüpunkt unterschiedliche
Daten darstellt. In der Regel ist der Arbeitsbereich in einen
Tabellenansicht (oben) und eine Detailansicht (unten, dient als
Vorschau) aufgeteilt. Zum Einsatz kommen neben den WinForms Controls
auch die Janus WinForms Controls.

Die Formulare für den Arbeitsbereich habe ich als UserControls
erstellt. Diese UserControls füllen den rechten Bereich komplett aus
(Dock=Fill). Im Vorschaubereich sind viele Controls enthalten, die als
Hintergrundfarbe Transparent verwenden und die sich teilweise in
Groupboxen befinden. In den Load-Ereignissen werden die entsprechenden
Daten aus der Datenbank geholt und an die Elemente gebunden.
Alle UserControls für den Arbeitsbereich sind von einem
"Haupt-UserControl" abgeleitet, welches verschiedene Eigenschaften und
Methoden zur Verfügung stellt, die ich überschreiben kann. Das
ansteuern und Anzeigen der UserControls aus dem Hauptprogramm erfolgt
so:
- Prüfung welches Control geladen werden soll
- Bildung einer neuen Instanz des Controls
- Unsichtbar setzen des Controls
- Setzen der verschiedenen Eigenschaften (z.B. DataSource, aktueller
Benutzer etc.)
- Einbindung in den rechten Bereich des Hautprogrammes
- Anzeige des Controls

Ich habe das Problem, dass man beim Laden der UserControls ein
Flackern sieht. Um dies zu verhindern habe ich bei jedem UserControl
im Konstruktor SetStyle gesetzt:
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);

Im Konstruktor und im Load-Ereignis wurden außerdem vor und nach den
aufgerufenen Methoden this.SuspendLayout() und this.ResumeLayout()
implementiert.
Dies führte zu keiner sichtbaren Reduktion des Flackerns. Auch das
setzen von Visible=false nach dem Instanzieren des Controls brachte
keine Besserung.
Danach habe ich in den Quellcode des Controls CreateParams
überschrieben.
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return result;
}
}

Jetzt flackert es weniger, aber dafür habe ich zwei neue
Erscheinungen:
1. Bei einigen verschachtelten Controls die Hintergrundfarbe nicht
mehr transparent angezeigt, sondern diese ist weiß.
2. Wenn ich einen Dialog über meine Anwendung lege und diesen mit der
Maus verschiebe, erhalte ich Schlieren auf dem Bildschirm.




da das WinForms-Modell auf GDI(+) basiert und GDI(+) nicht unbedingt für
graphische Anwendungen taut, ist hier die Leistungsfàhigheit schnell
ausgeschöpft. Gerade wenn es um solche Dinge wie Transparenzen und
ineinander geschachtelte Steuerelemente geht passiert dies sehr schnell.
Wenn Dir soviel am flackern liegt (ich weiß, dass es nicht schön aussieht),
solltest Du vielleicht auf WPF umsteigen.

MfG

Carsten Unterberg | Test-Framework
http://test-framework.blogspot.com/

Ähnliche fragen