PictureBox wird mittels Maus verschoben – nun lädt das Bild schlecht

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    PictureBox wird mittels Maus verschoben – nun lädt das Bild schlecht

    Hi,
    ich habe ein Testprojekt erstellt, in dem ich mit der linken Maustaste eine PictureBox verschiebe. Leider wird das Bild bei schnellen Bewegungen schlecht angezeigt. Woran kann das liegen? Ich habe mitbekommen, dass das MouseMove-Event sehr oft aufgerufen wird (wahrscheinlich bei jedem PIxel?) und meine Vermutung ist, dass das Framework nicht hinterherkommt? Mein PC ist neu!

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private es_wird_geklickt As Boolean = False
    3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. If System.IO.File.Exists(Application.StartupPath & "\Klammer klein.jpg") Then
    5. PictureBox_Klammer.Image = Image.FromFile(Application.StartupPath & "\Klammer klein.jpg")
    6. End If
    7. End Sub
    8. Private Sub PictureBox_Klammer_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox_Klammer.MouseUp
    9. Dim MP As Point = MousePosition()
    10. PictureBox_Klammer.Location = New Point(CInt(MP.X - 187 / 2.0), 500)
    11. es_wird_geklickt = False
    12. End Sub
    13. Private Sub PictureBox_Klammer_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox_Klammer.MouseMove
    14. If es_wird_geklickt Then
    15. Dim MP As Point = MousePosition()
    16. PictureBox_Klammer.Location = New Point(CInt(MP.X - 187 / 2.0), 500)
    17. End If
    18. End Sub
    19. Private Sub PictureBox_Klammer_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox_Klammer.MouseDown
    20. es_wird_geklickt = True
    21. End Sub
    22. End Class



    Noch einen schönen Abend und einen frohen 1. Advent morgen
    Bilder
    • 20201128_162459_007_saved - Kopie.jpg

      4,77 MB, 4.032×3.024, 44 mal angesehen
    • 20201128_162459_009_saved - Kopie.jpg

      5,8 MB, 4.032×3.024, 46 mal angesehen
    • 20201128_162459_023 - Kopie.jpg

      3,21 MB, 4.032×3.024, 45 mal angesehen
    Das liegt vermutlich daran, dass bei jeder Bewegung der PictureBox ein Rerendering des entsprechenden Bereichs des Fensters getriggert wird, bis diese dann ausgeführt wird aber dann schon wieder die PictureBox noch weiter bewegt wurde. Sinnvoll wäre es hier, einfach ein eigenes Control zu erstellen, was einfach immer das Bild an die richtige Stelle zeichnet - damit sollte sich das Problem lösen lassen.
    ein eigenes Control zu erstellen
    @nafets Danke! Wie meinst du das und wie geht das?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Ich habe ein Bild im Designer der Image-Property zugewiesen.
    Beim schnellen Bewegen selbst ist das Bild etwas verzerrt, aber den Effekt wie auf Deinen Bildern kann ich nicht reproduzieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Danke fürs Ausprobieren! :) Ich habe das nachgemacht. Selber Fehler.

    Habe mal 1 Minute lang die Maus und PictureBox hin- und herbewegt: CPU und GPU lachen sich tot. Daran kann's nicht liegen. Ist mit dem Code alls ok?

    Edit: vielleicht helfen diese Infos: die Picturebox, die das Bild mit der Klammer enthält, enthält keinen Background! Das Bild selbst hat die Farbe wie das Form. Also ne Klammer auf grauem Grund. Habe ich bei Powerpoint gemacht. Das Bild ist ein JPG mit 6 kB.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Bartosz“ ()

    @Bartosz Poste mal Deine JPG.
    Meine hat 191KB.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    RFD ok gerne
    Bilder
    • Klammer klein.jpg

      5,76 kB, 374×145, 36 mal angesehen
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Bartosz schrieb:

    RFD
    :?:
    Ansonsten daselbe Verhalten wie eben, ich würde sagen "völlig normal".
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Sorry, meinte RFG - deine Abkürzung.
    Also liegt das jetzt an meinem PC? Oder meintest du, der Effekt ist normal?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Keine Ahnung, ich kann Deinen Effekt nicht reproduzieren, d.h., ich kann keinen Screenshot produzieren, der solche Bilder liefert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Bartosz schrieb:

    ein eigenes Control zu erstellen
    Wie meinst du das und wie geht das?

    Anstatt dass du eine PictureBox über die Form schiebst, würde ich ein eigenes custom Control erstellen, das per OwnerDrawing gezeichnet wird: Du machst deine eigene Klasse, die von ​Control erbt, überschreibst die ​OnPaint-Methode und zeichnest da dein Bild an der aktuellen Position in diesem Control. Die Maus-Events kannst du eigentlich genauso wie jetzt implementieren, nur dass du anstatt der PictureBox die irgendwo gespeicherte Position aktualisierst und danach ​DeinCustomControl.Invalidate() aufrufst, wodurch dein Control neu gezeichnet wird und du dann in der ​OnPaint-Methode das Bild an der neuen Position zeichnen kannst.
    Damit kannst du diesem Problem komplett vorbeugen, außerdem ist es ressourcenschonend(er) und sauberer - Controls sind nämlich nicht dafür gemacht, sie wild hin und her zu bewegen, weswegen man das vermeiden sollte, wenn es sich mit relativ wenig Aufwand verhindern lässt.
    Controls sind nämlich nicht dafür gemacht, sie wild hin und her zu bewegen
    Ja ich weiß, hab ich schon öfter hier gelesen :whistling:

    Danke @nafets Muss ich mal ausprobieren.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.