draw rectangle und picturebox verschieben sich nach zoom?

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von _Bob.

    draw rectangle und picturebox verschieben sich nach zoom?

    Hallo ihr,

    bin ein relativer anfänger in VB aber probier gerne etwas aus.

    Jetzt hatte ich eine Art Fotoanzeige gemacht, die Bilder in Ardnern anzeigt, durch Klick auf das angezeigte Bild (unsichtbare "Rectangle"), das nächste Bild anzeigt, und zoomen kann.
    Funktioniert auch alles einzeln, aber sobald ich zoome und das "Rectangle" neu skaliere, verschiebt es sich, obwohl die "location" und "size" eigentlich passen sollte...
    Anbei der entsprechende Code:

    Quellcode

    1. Public Class Form1
    2. Private _originalLocation As New Point
    3. Private _originalSize As Size = Nothing
    4. Private _scale As Single = 1
    5. Private _scaleDelta As Single = 0.0001
    6. Dim l As Rectangle
    7. Dim r As Rectangle
    8. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    9. PictureBox1.Size = Panel1.Size
    10. PictureBox1.SizeMode = PictureBoxSizeMode.Zoom
    11. PictureBox1.Image = Bitmap.FromFile("bild_url")
    12. _originalLocation = PictureBox1.Location
    13. l = New Rectangle(PictureBox1.Location.X,
    14. PictureBox1.Location.Y,
    15. PictureBox1.Width / 2,
    16. PictureBox1.Height)
    17. r = New Rectangle(PictureBox1.Location.X + (PictureBox1.Width / 2),
    18. PictureBox1.Location.Y,
    19. PictureBox1.Width / 2,
    20. PictureBox1.Height)
    21. If PictureBox1.Image IsNot Nothing Then
    22. PictureBox1.Size = Panel1.Size
    23. _originalSize = Panel1.Size
    24. End If
    25. End Sub
    26. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    27. _scaleDelta = Math.Sqrt(PictureBox1.Width * PictureBox1.Height) * 0.0001
    28. _scale += _scaleDelta
    29. PictureBox1.Size = New Size(CInt(Math.Round(_originalSize.Width * _scale)),
    30. CInt(Math.Round(_originalSize.Height * _scale)))
    31. PictureBox1.Location = New Point(_originalLocation.X - ((PictureBox1.Width - Panel1.Width) / 2),
    32. _originalLocation.Y - ((PictureBox1.Height - Panel1.Height) / 2))
    33. l = New Rectangle(PictureBox1.Location.X,
    34. PictureBox1.Location.Y,
    35. PictureBox1.Width / 2,
    36. PictureBox1.Height)
    37. r = New Rectangle(PictureBox1.Location.X + (PictureBox1.Width / 2),
    38. PictureBox1.Location.Y,
    39. PictureBox1.Width / 2,
    40. PictureBox1.Height)
    41. End Sub
    42. End Class

    Button1 zoomt das Bild.
    Das Panel beinhaltet die Picturebox.

    Meiner Logik nach sollten die "Rectangle" nach dem zoom aktualisiert werden und wieder passen. tun sie aber nicht.
    Bin für jede hilfe dankbar!

    Grüße,
    _Bob

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „_Bob“ ()

    @_Bob Willkommen im Forum. :thumbup:
    Was soll denn passieren, wenn auf den Button gedrückt wird?
    Wenn ich nach Deiner Beschreibung ein Projekt nachbaue, bleibt beim Zoom das Zentrum erhalten und das Bild "wächst" nach außen.
    Dazu habe ich das Panel mit .Anchor = All an der Form fixiert und die PictureBox mit .Anchor = None relativ zum Panel fixiert (der Mittelpunkt bleibt erhalten).
    Du siehst, das dies alles im Designer passiert, und Deinen Designer-Code kennen wir nicht. Er steht in der Datei Form1.Designer.vb.
    =====
    Wenn Du gerade anfängst, mit VB.NET zu "spielen" beherzige sofort dies hier: Visual Studio - Empfohlene Einstellungen
    Für Dich bedeutet das unmittelbar Option Strict On. Arbeite mit den Typen, die Du meinst.
    Auf Deinen Code angewendet: 2 Mal Single => Double und Integer-Division mit dem Backslash: PictureBox1.Width / 2 => PictureBox1.Width \ 2.
    Und:
    Welche Funktion genau kaben die Rechtecke l und r in Deinem Programm? Wo werden sie verwendet?
    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!
    Hey Rod,

    danke schon mal für deine Antwort!
    Das bild soll auch nach außen wachsen, das ist so beabsichtigt. die rechtecke aber auch.
    Die Rechtecke sind dafür da, um mit einem Klick via Picturebox1.Mousedown auf das Bild, das nächste oder vorherige Bild einer Galerie zu laden (Quasi unsichtbare Schaltflächen). Funktioniert ohne den Zoom auch ohne Probleme.
    Die .Anchor sind wie du beschrieben hast.
    Anbei Bilder wie es sein sollte bzw wie es ist.

    Spoiler anzeigen

    Bild 1 ist die Picturebox:


    Bild 2 zeigt die (hier sichtbar gemachten) Rechtecke, so wie sie sein sollen:


    In Bild 3 ist die Picturebox gezoomt, die Rechtecke verschieben sich aber zunehmend mit zunehmendem Zoom nach Links:


    Und danke für deinen Link! Ich arbeite mich da heute mal durch!

    Gruß Bob

    _Bob schrieb:

    Meiner Logik nach sollten die "Rectangle" nach dem zoom aktualisiert werden und wieder passen. tun sie aber nicht.
    Jo, mMn auch.
    Kannst du das Projekt, oder ein Testprojekt anhängen, was den Fehler reproduziert?

    Und wenns umständlich ist, bitte auch die Schritte erklären für Doofe, wie man das Fehlverhalten herbeiführt?

    Anleitung zum Anhängen von Dateien:




    edit: Ah - könnte was mitte AutoScrollPosition zu tun haben - nicht soo einfach zu erklären - solange kein Testprojekt vorliegt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Kannst du das Projekt, oder ein Testprojekt anhängen, was den Fehler reproduziert?

    Klar, hier ist es: Testprojekt.7z
    Ich denke nicht, dass es noch weitere Erklärung braucht; aber falls doch, gib doch bescheid.
    Einfach den Pfad zu einer existierenden Datei ändern. Die Button sollten auch selbsterklärend sein.

    Bin für jede hilfe dankbar! Wiegesagt ich bin neu. :)

    P.s. ich habe mal versucht Rod's Rat zu befolgen obwohl ich Single => Double (noch) nicht verstehe.

    _Bob schrieb:

    Single => Double
    Das beseitigt Fehler, die durch Option Strict On hervorgerufen werden.

    =====
    Ich finde, dass sich Dein Programm völlig korrekt verhält.
    Was soll denn passieren, wenn geklickt wird?
    Kannst Du das mal skizzieren?
    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!
    Deine Berechnungen sind mathematisch nicht verkehrt, aber die Ergebnisse werden im falschen Kontext verwendet.
    Jedes Control hat sein eigenes Koordinatensystem.
    Die Location eines Controls bezieht sich aufs Koordinatensystem des ParentControls - also PicBox.Location ist bezogen aufs Panel1.
    Picbox.MouseMove, Picbox.Paint etc. beziehen die Koordinaten aber auf die PicBox selbst, und darum ist alles verschoben, sobald PicBox und Panel nicht exakt gleich gross sind.
    Also in Rechnungen, die Rechtecke innerhalb der Picbox berechnen, darf PicBox.Location nicht einfliessen.
    Stattdessen PicBox.ClientRectangle zugrundelegen.

    Ich habs mal komplett neu gemacht, auch mit
    Option Strict On!


    Befolge Visual Studio - Empfohlene Einstellungen - ist wichtig.
    Andernfalls kommt man übrigens auch leicht zu dem Schluss, du seist beratungsresistent, und es habe daher kein Sinn, dir was zu erklären.
    Dateien
    • Testprojekt.zip

      (12,63 kB, 247 mal heruntergeladen, zuletzt: )
    ErfinderDesRades,

    vielen Dank dir!!
    Jetzt funktioniert alles wie es soll und ich verstehe im Prinzip auch was du meinst!
    (Ich war der Meinung wenn ich in der picBox mahle, dass ich auch ​picBox.location als bezug brauche. Jetzt weiss ich es besser :D)

    @Rod: Ich meinte damit, dass ich mir nicht ganz im Klaren bin, was der Unterschied zw. Single und Double ist und wann ich was verwende. Aber wie gesagt: Da werde ich mich einlesen und es in zukunft beachten/beherzigen.
    Die ​Option Strict On! ist jetzt auch aktiviert.

    Nochmals danke an euch beide!

    Grüße
    _Bob