Fenster andocken und abdocken

    • VB.NET

      Fenster andocken und abdocken

      Ich habe mich mit diesem Thema auseinander gesetzt und folgende Lösung gefunden. Der Punkt war eigentlich folgendes. Ein User klickt ein Bild an und verschiebt die Form wo anders hin. Das Bild sollte aber angedockt folgen, aber auch abgedockt nicht folgen. Es sollte überall hin verschoben werden können aber nur an bestimmten Positionen als quasi docked erscheinen. Dabei wollte ich nicht, das das aufrufende Fenster die Arbeit verrichtet, sondern das das Bilderfenster von selbst erkennt, das etwas bestimmtes geschieht.

      Dazu habe ich einfach eine Form erstellt.

      VB.NET-Quellcode

      1. Public Class Form1
      2. Private f2 As New Form2(Me)
      3. Private Sub Form1_Move(sender As Object, e As System.EventArgs) Handles Me.Move
      4. Me.Text = "X: " & Me.DesktopLocation.X & " Y: " & Me.DesktopLocation.Y
      5. End Sub
      6. Private Sub Form1_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
      7. f2.Show()
      8. End Sub
      9. End Class


      Dieses Fenster zeigt einfach nur in seinem Titel die Position auf dem Desktop an. Zudem wird die Form2 alias f2 geöffnet.

      Quellcode Form2
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Form2
      2. Private WithEvents _Owner As Form
      3. Private Docked As Boolean = True
      4. Public Sub New(owner As Form)
      5. InitializeComponent()
      6. _Owner = owner
      7. End Sub
      8. Private Sub Form2_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
      9. Me.Location = DefaultLocation()
      10. End Sub
      11. Private Sub _Owner_Move(sender As Object, e As System.EventArgs) Handles _Owner.Move
      12. If Docked = True Then
      13. Me.Location = DefaultLocation()
      14. End If
      15. End Sub
      16. Private Sub Form2_Move(sender As Object, e As System.EventArgs) Handles Me.Move
      17. Me.Text = "X: " & Me.DesktopLocation.X & " Y: " & Me.DesktopLocation.Y
      18. 'Checking X and Y Location
      19. If ((Me.DesktopLocation.X) > (_Owner.DesktopLocation.X + _Owner.Width + 20)) Or ((Me.DesktopLocation.X) < (_Owner.DesktopLocation.X + _Owner.Width - 20)) _
      20. Or ((Me.DesktopLocation.Y) > (_Owner.DesktopLocation.Y + 20)) Or ((Me.DesktopLocation.Y) < (_Owner.DesktopLocation.Y - 20)) Then
      21. Docked = False
      22. Else
      23. Me.Location = DefaultLocation()
      24. Docked = True
      25. End If
      26. End Sub
      27. Private Function DefaultLocation() As System.Drawing.Point
      28. Return New System.Drawing.Point(_Owner.DesktopLocation.X + _Owner.Width, _Owner.DesktopLocation.Y)
      29. End Function
      30. End Class



      Die TopMost Eigenschaft von Form2 wurde auf True gesetzte. Wenn man dies nicht tut, dann wird die Form zwar angezeigt, aber gerne hinter andere Formulare verschwinden. Eine Lösung dafür habe ich bisher nur darin gefunden einige Ereignisse direkt zu prüfen und dann die Form2 einfach zu schliessen. Ihr werdet aber schnell feststellen was ich meine.

      Im Prinzip funktioniert das Ganze so. Form2 erkennt das Ereignis Form.Move wenn Form2 selber als docked gekennzeichnet ist, dann wird sie der _Owner oder Form1 folgen. Ist Form2 selber nicht als docked gekennzeichnet dann folgt sie nicht. Form2 erkennt das selber, indem sie selber prüft ob sie sich in einem bestimmten Fenster bewegt. Das Fenster besteht darin, das um Form1 an der rechten oberen Ecke ein imaginäres kleines Quadrat von 40x40 Pixel erzeugt wird, auf dessen die eigene Position geprüft wird.

      VB.NET-Quellcode

      1. If ((Me.DesktopLocation.X) > (_Owner.DesktopLocation.X + _Owner.Width
      2. + 20)) Or ((Me.DesktopLocation.X) < (_Owner.DesktopLocation.X +
      3. _Owner.Width - 20))
      4. Or ((Me.DesktopLocation.Y) >
      5. (_Owner.DesktopLocation.Y + 20)) Or ((Me.DesktopLocation.Y) <
      6. (_Owner.DesktopLocation.Y - 20)) Then
      7. Docked = False
      8. Else
      9. Me.Location = DefaultLocation()
      10. Docked = True
      11. End If


      Ich hoffe es hat euch geholfen. Für eine Lösung des TopMost, wäre ich trotzdem dankbar. :rolleyes: