Panel Flackert

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Glossy Cherry.

    Panel Flackert

    Hey,
    Ich habe folgenden Code:

    VB.NET-Quellcode

    1. Dim x As Integer
    2. Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    3. x = e.Location.X
    4. End Sub
    5. Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    6. Refresh()
    7. e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.Default
    8. e.Graphics.DrawRectangle(Pens.Red, New Rectangle(New Point(x, 0), New Size(1, 15)))
    9. End Sub
    10. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    11. Me.SetStyle(ControlStyles.DoubleBuffer, True)
    12. Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    13. End Sub


    Und der Strich welcher gezeichnet wird, flackert wie verückt, trotz double buffering, setstyle usw.

    Greetz
    Moderatorin: "Apropo ritzen.." Shin Chan: "hoho sie hat Po ritze gesagt"
    "saying to buy a mac because your anti-virus expired is like saying you're out of condoms so you're just going to go fuck dudes"
    "Wie auch in anderen Threads kann ich leider nichts bieten außer vielleicht spaß beim Skypen aber mehr leider auch nicht." - Sind kinder pornos nicht verboten?
    Entferne das Refresh() aus dem OnPaint-Event.
    Sobald dein Panel neu gezeichnet wird (OnPaint) , wird es mittels Refresh() erneut gezeichnet.
    Das ist etwa äquivalent zu diesem Code:

    VB.NET-Quellcode

    1. Do
    2. Me.invalidate()
    3. Loop



    Guck dir dazu diesen Artikel mal an (Wann benutzt wann welche Methode?).

    Bei Form_MouseMove solltest du noch ein Invalidate() einfügen.

    Liebe Grüße
    /nicht getestet

    VB.NET-Quellcode

    1. Sub refreshit()
    2. Dim backbuffer As New Bitmap(Panel1.ClientRectangle.Width, Panel1.ClientRectangle.Height)
    3. Using g As Graphics = Graphics.FromImage(backbuffer)
    4. g.CompositingMode = Drawing2D.CompositingMode.SourceOver
    5. g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
    6. g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
    7. g.Clear(Color.White)
    8. 'dein stuff zeichnen
    9. Panel1.CreateGraphics().DrawImageUnscaled(backbuffer, 0, 0)
    10. End Using
    11. backbuffer.Dispose()
    12. End Sub


    anders kann man afaik ein control nicht flackerfrei neu zeichnen weil beim refresh per .clear alles gelöscht wird
    Oh Gott....
    Also:

    VB.NET-Quellcode

    1. Public Class NichtFlackernderPanel
    2. Inherits System.Windows.Forms.Panel
    3. Sub New()
    4. MyBase.New()
    5. MyBase.SetStyle(System.Windows.Forms.ControlStyles.UserPaint, True)
    6. MyBase.SetStyle(System.Windows.Forms.ControlStyles.AllPaint, True) 'AllPaintWM oder so kp
    7. MyBase.SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
    8. End Sub
    9. End Class
    wenn dann

    VB.NET-Quellcode

    1. Public Class NichtFlackernderPanel
    2. Inherits System.Windows.Forms.Panel
    3. Sub New()
    4. MyBase.New()
    5. MyBase.SetStyle(System.Windows.Forms.ControlStyles.UserPaint Or System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
    6. End Sub
    7. End Class

    Glossy Cherry schrieb:

    Und der Strich welcher gezeichnet wird, flackert wie verückt, trotz double buffering, setstyle usw.
    Wurde schon angesprochen, dass der Fehler mittm Refresh zusammenhängt.
    Jedoch ohne jede Erläuterung, was den Fehler verursacht, und wie mans richtig anfängt:

    VB.NET-Quellcode

    1. Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    2. Refresh()
    3. e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.Default
    4. e.Graphics.DrawRectangle(Pens.Red, New Rectangle(New Point(x, 0), New Size(1, 15)))
    5. End Sub
    Was macht Refresh? Es erzwingt einen erneuten Zeichnungsvorgang. Was passiert im Zeichnungsvorgang? Das Paint-Event wird aufgerufen.
    Folge: Eine Endlos-Ereigniskette, Flackern und vergleichsweise aberwitzige Cpu-Last.

    Refresh soll man sowieso vermeiden, weil es den Zeichnungsvorgang erzwingt, sofort!.
    Nimm Invalidate, das fordert den Zeichnungsvorgang nur an, und überläßt es Windows, intern zum geeignetsten Zeitpunkt _Paint() zu feuern.

    Aber v.a. ists natürlich idiotisch, in der Zeichen-Methode selbst ein Neuzeichnen anzufordern, denn es wird ja soeben neu gezeichnet.
    Sinnvollerweise fordert man ein Neuzeichnen nur an, wenn sich das zu zeichnende geändert hat - weil wozu soll man sonst Neuzeichnen?

    Im Beispiel ändert sich das zu zeichnende im MouseMove, also ist dort auch Invalidate() aufzurufen.
    @ErfinderDesRades: Wenn ich so mache wie du es mir geraten hast:

    VB.NET-Quellcode

    1. Dim x As Integer
    2. Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    3. x = e.Location.X
    4. Invalidate()
    5. End Sub
    6. Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
    7. e.Graphics.DrawRectangle(Pens.Red, New Rectangle(New Point(x, 0), New Size(1, 15)))
    8. End Sub


    Wird der Strich 1x gezeichnet und danach bleibt er für die ganze zeit an der selben Stelle?

    Wenn ich jetzt jedoch Refresh anstatt Invalidate nehme, wird es ideal gezeichnet jedoch beim bewegen flackert es. :D
    Moderatorin: "Apropo ritzen.." Shin Chan: "hoho sie hat Po ritze gesagt"
    "saying to buy a mac because your anti-virus expired is like saying you're out of condoms so you're just going to go fuck dudes"
    "Wie auch in anderen Threads kann ich leider nichts bieten außer vielleicht spaß beim Skypen aber mehr leider auch nicht." - Sind kinder pornos nicht verboten?

    Glossy Cherry schrieb:

    @ErfinderDesRades: Wenn ich so mache wie du es mir geraten hast,...
    Wird der Strich 1x gezeichnet und danach bleibt er für die ganze zeit an der selben Stelle?
    glaub ich nicht.
    Kannst du das Projekt zippen + hochladen?

    Achso - glaub, sehe Fehler: Das MouseMove behandelt Form1.MouseMove, das Paint-Event aber Panel1_Paint - ist das beabsichtigt?
    Ja ist es, ich hab es schon gelöst: eine Mischung aus dem Panel Code und Doublebuffering etc. ;)
    Moderatorin: "Apropo ritzen.." Shin Chan: "hoho sie hat Po ritze gesagt"
    "saying to buy a mac because your anti-virus expired is like saying you're out of condoms so you're just going to go fuck dudes"
    "Wie auch in anderen Threads kann ich leider nichts bieten außer vielleicht spaß beim Skypen aber mehr leider auch nicht." - Sind kinder pornos nicht verboten?