Ich habe zwei Probleme mit einer eigenen Benutzersteuerung, die Bitmaps verwendet:eigene WinForms Kontrolle flackert und hat schlechte Leistung
- Es flackert, wenn es über .NET der ‚Refresh‘ Methode neu gezeichnet wird.
- Es hat eine schlechte Leistung.
Die Steuerung besteht aus drei Bitmaps:
- Eine statische Hintergrundbild.
- Ein rotierender Rotor.
- Ein anderes Bild, abhängig vom Rotorwinkel.
Alle verwendeten Bitmaps haben eine Auflösung von 500x500 Pixel. Das Steuerelement funktioniert so: https://www.dropbox.com/s/t92gucestwdkx8z/StatorAndRotor.gif (es ist eine GIF-Animation)
Die Benutzersteuerung sollte sich selbst zeichnen, jedes Mal wenn es einen neuen Rotorwinkel bekommt. Daher hat es ein öffentliches Eigentum ‚RotorAngle‘, die wie folgt aussieht:
public double RotorAngle
{
get { return mRotorAngle; }
set
{
mRotorAngle = value;
Refresh();
}
}
Refresh
wirft die Paint
Ereignis. Die OnPaint
Event-Handler sieht wie folgt aus:
private void StatorAndRotor2_Paint(object sender, PaintEventArgs e)
{
// Draw the three bitmaps using a rotation matrix to rotate the rotor bitmap.
Draw((float)mRotorAngle);
}
Aber wenn ich diesen Code verwenden - die auch in anderen eigenen Bedienelemente arbeitet - der Benutzer die Steuerung überhaupt nicht gezogen, wenn die Kontrolle über Doppel SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
gepuffert. Wenn ich dieses Flag nicht auf "true" setze, flackert das Steuerelement, wenn es neu gezeichnet wird.
Im Steuer Konstruktor Ich habe:
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ContainerControl, false);
// User control is not drawn if "OptimizedDoubleBuffer" is true.
// SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
Zuerst dachte ich, es flackert, weil der Hintergrund jedes Mal gelöscht wird die Steuerung gezogen wird. Daher setze ich SetStyle(ControlStyles.AllPaintingInWmPaint, true)
. Aber es hat nicht geholfen.
Also, warum flimmert es? Andere Steuerelemente funktionieren sehr gut mit diesem Setup. Und warum wird die Steuerung nicht gezeichnet, wenn .
Ich fand heraus, dass die Steuerung nicht, ob ich meine Draw
Methode nach der Eigenschaft RotorAngle
Ändern direkt aufrufen nicht flimmern:
public float RotorAngle
{
get { return mRotorAngle; }
set
{
mRotorAngle = value;
Draw(mRotorAngle);
}
}
Aber dies führt zu einer sehr schlechten Leistung, vor allem im Vollbildmodus. Es ist nicht möglich, das Steuerelement alle 20 Millisekunden zu aktualisieren. Sie können es selbst ausprobieren. Ich werde die vollständige Visual Studio 2008-Lösung unten anhängen.
Also, warum ist es so eine schlechte Leistung? Es ist kein Problem, andere (eigene) Kontrollen alle 20 Millisekunden zu aktualisieren. Liegt es wirklich nur an den Bitmaps?
habe ich eine einfache visuelle Visual Studio 2008-Lösung, die beiden Probleme zu demonstrieren: bin\Debug
https://www.dropbox.com/s/mckmgysjxm0o9e0/WinFormsControlsTest.zip (289,3 KB)
Es ist eine ausführbare Datei im Verzeichnis.
Danke für Ihre Hilfe.
ich nicht in alle Details jetzt gehen, aber Sie brauchen, um das doppelte Pufferung zu suchen. Glücklicherweise ist es sehr einfach in 2008+ Die Art, wie Sie die Aktualisierung in der Eigenschaft tun, ist auch schlecht. – Ian
Bitte double-buffer nicht, wenn Ihre Anwendung über Remote-Desktop verwendet wird - siehe [diesen Link] (http://blogs.msdn.com/b/oldnewthing/archive/2006/01/03/508694.aspx) . Sie können prüfen, ob es sich bei der aktuellen Sitzung um einen Remote-Desktop handelt: 'if (SystemInformation.TerminalServerSession) ...' – Bridge