Es ist nicht die Art von Flimmern, die durch Doppelpufferung gelöst werden kann. Weder BeginUpdate noch SuspendLayout. Sie haben zu viele Steuerelemente, das BackgroundImage kann es noch viel schlimmer machen.
Es beginnt, wenn sich das UserControl selbst malt. Es zeichnet das BackgroundImage und hinterlässt Löcher in den Fenstern der untergeordneten Steuerung. Jedes untergeordnete Steuerelement erhält dann eine Nachricht, um sich selbst zu malen. Sie füllen das Loch mit ihrem Fensterinhalt aus. Wenn Sie viele Steuerelemente haben, sind diese Löcher für den Benutzer für eine Weile sichtbar. Sie sind normalerweise weiß und bilden einen schlechten Kontrast zum BackgroundImage, wenn es dunkel ist. Oder sie können schwarz sein, wenn für das Formular die Eigenschaft Deckkraft oder Transparenzschlüssel festgelegt ist, die sich stark von fast allem abhebt.
Dies ist eine ziemlich grundlegende Einschränkung von Windows Forms. Sie hängt von der Art und Weise ab, wie Windows Windows rendert. Übrigens von WPF behoben, verwendet es keine Fenster für untergeordnete Steuerelemente. Sie möchten das gesamte Formular einschließlich der untergeordneten Steuerelemente doppelt puffern. Das ist möglich, überprüfen Sie meinen Code in diesem Thread für die Lösung. Es hat jedoch Nebenwirkungen und erhöht die Malgeschwindigkeit nicht wirklich. Der Code ist einfach. Fügen Sie ihn in Ihr Formular ein (nicht in das Benutzersteuerelement):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Es gibt viele Dinge, die Sie tun können, um die Malgeschwindigkeit zu verbessern, bis das Flimmern nicht mehr wahrnehmbar ist. Beginnen Sie mit dem BackgroundImage. Sie können sehr teuer sein, wenn das Quellbild groß ist und verkleinert werden muss, um in das Steuerelement zu passen. Ändern Sie die BackgroundImageLayout-Eigenschaft in "Tile". Wenn dies zu einer spürbaren Beschleunigung führt, kehren Sie zu Ihrem Malprogramm zurück und ändern Sie die Bildgröße, um eine bessere Übereinstimmung mit der typischen Steuerelementgröße zu erzielen. Oder schreiben Sie Code in die OnResize () -Methode des UC, um eine Kopie des Bildes mit der richtigen Größe zu erstellen, damit die Größe nicht jedes Mal geändert werden muss, wenn das Steuerelement neu gezeichnet wird. Verwenden Sie für diese Kopie das Pixelformat Format32bppPArgb. Es wird etwa zehnmal schneller gerendert als jedes andere Pixelformat.
Als nächstes können Sie verhindern, dass die Löcher so auffällig sind und einen schlechten Kontrast zum Bild bilden. Sie können das WS_CLIPCHILDREN-Stilflag für die UC deaktivieren. Dieses Flag verhindert, dass die UC in dem Bereich malt, in dem sich die untergeordneten Steuerelemente befinden. Fügen Sie diesen Code in den Code von UserControl ein:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Die untergeordneten Steuerelemente malen sich jetzt über das Hintergrundbild. Sie können immer noch sehen, wie sie sich einzeln malen, aber das hässliche weiße oder schwarze Zwischenloch ist nicht sichtbar.
Last but not least ist die Reduzierung der Anzahl der untergeordneten Steuerelemente immer ein guter Ansatz, um Probleme beim langsamen Malen zu lösen. Überschreiben Sie das OnPaint () - Ereignis der UC und zeichnen Sie, was jetzt in einem untergeordneten Element angezeigt wird. Bestimmte Beschriftungen und PictureBox sind sehr verschwenderisch. Praktisch für Zeigen und Klicken, aber ihre leichte Alternative (Zeichnen einer Zeichenfolge oder eines Bildes) benötigt in Ihrer OnPaint () -Methode nur eine einzige Codezeile.
UpdateStyles
nach dem Einstellen angerufen ? Es ist schlecht dokumentiert, kann aber manchmal notwendig sein.