Imports System.Drawing Imports System.Windows.Forms Public Class ClassSnapPanel Inherits Panel Private _ShowGrid As Boolean = True Private _GridSize As Integer = 16 Private _NeedsScrollUpdate As Boolean = False Public Sub New() Me.AutoScroll = True Me.DoubleBuffered = True ' Flackern reduzieren End Sub Public Property GridSize As Integer Get Return _GridSize End Get Set(value As Integer) If value > 0 AndAlso value <> _GridSize Then _GridSize = value Invalidate() End If End Set End Property Public Property ShowGrid As Boolean Get Return _ShowGrid End Get Set(value As Boolean) If value <> _ShowGrid Then _ShowGrid = value Invalidate() End If End Set End Property Protected Overrides Sub OnControlAdded(e As ControlEventArgs) MyBase.OnControlAdded(e) AddHandler e.Control.LocationChanged, AddressOf AlignToGrid AddHandler e.Control.MouseUp, AddressOf AlignToGrid ScheduleScrollUpdate() End Sub Protected Overrides Sub OnControlRemoved(e As ControlEventArgs) MyBase.OnControlRemoved(e) RemoveHandler e.Control.LocationChanged, AddressOf AlignToGrid RemoveHandler e.Control.MouseUp, AddressOf AlignToGrid ScheduleScrollUpdate() End Sub Protected Overrides Sub OnLayout(levent As LayoutEventArgs) MyBase.OnLayout(levent) ScheduleScrollUpdate() End Sub Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) If Not Me.DesignMode AndAlso _ShowGrid Then Dim scrollOffset As Point = Me.AutoScrollPosition Dim gridRect As New Rectangle(-scrollOffset.X, -scrollOffset.Y, Me.ClientSize.Width, Me.ClientSize.Height) ControlPaint.DrawGrid(e.Graphics, gridRect, New Size(_GridSize, _GridSize), Me.BackColor) End If End Sub Private Sub AlignToGrid(sender As Object, e As EventArgs) If Not _ShowGrid OrElse Me.DesignMode Then Return Dim ctrl As Control = CType(sender, Control) Dim x As Integer = Math.Floor(ctrl.Left / _GridSize) * _GridSize Dim y As Integer = Math.Floor(ctrl.Top / _GridSize) * _GridSize ctrl.Location = New Point(x, y) ScheduleScrollUpdate() End Sub Private Sub ScheduleScrollUpdate() If Not _NeedsScrollUpdate Then _NeedsScrollUpdate = True BeginInvoke(New MethodInvoker(Sub() UpdateScrollArea() _NeedsScrollUpdate = False End Sub)) End If End Sub Private Sub UpdateScrollArea() Dim maxWidth As Integer = 0 Dim maxHeight As Integer = 0 For Each ctrl As Control In Me.Controls maxWidth = Math.Max(maxWidth, ctrl.Right) maxHeight = Math.Max(maxHeight, ctrl.Bottom) Next Me.AutoScrollMinSize = New Size(maxWidth, maxHeight) End Sub End Class 'Public Class ClassSnapPanel ' Inherits Panel ' Private _ShowGrid As Boolean = True ' Private _GridSize As Integer = 16 ' Public Sub New() ' Me.AutoScroll = True ' Scrollbars aktivieren ' End Sub ' Public Property GridSize As Integer ' Get ' Return _GridSize ' End Get ' Set(value As Integer) ' _GridSize = value ' Refresh() ' End Set ' End Property ' Public Property ShowGrid As Boolean ' Get ' Return _ShowGrid ' End Get ' Set(value As Boolean) ' _ShowGrid = value ' Refresh() ' End Set ' End Property ' Protected Overrides Sub OnControlAdded(e As ControlEventArgs) ' AddHandler e.Control.LocationChanged, AddressOf AlignToGrid ' AddHandler e.Control.DragDrop, AddressOf AlignToGrid ' MyBase.OnControlAdded(e) ' UpdateScrollArea() ' End Sub ' Protected Overrides Sub OnControlRemoved(e As ControlEventArgs) ' RemoveHandler e.Control.LocationChanged, AddressOf AlignToGrid ' RemoveHandler e.Control.DragDrop, AddressOf AlignToGrid ' MyBase.OnControlRemoved(e) ' UpdateScrollArea() ' End Sub ' Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs) ' If _ShowGrid Then ' ControlPaint.DrawGrid(e.Graphics, ClientRectangle, New Size(_GridSize, _GridSize), BackColor) ' End If ' MyBase.OnPaint(e) ' End Sub ' Private Sub AlignToGrid(sender As Object, e As EventArgs) ' If _ShowGrid Then ' Dim item As Control = CType(sender, Control) ' Dim x As Integer = Math.Round(item.Left / _GridSize) * _GridSize ' Dim y As Integer = Math.Round(item.Top / _GridSize) * _GridSize ' item.Location = New Point(x, y) ' UpdateScrollArea() ' End If ' End Sub ' Private Sub UpdateScrollArea() ' Dim maxWidth As Integer = 0 ' Dim maxHeight As Integer = 0 ' ' Größte X- und Y-Koordinate der enthaltenen Controls bestimmen ' For Each ctrl As Control In Controls ' Dim right As Integer = ctrl.Right ' Dim bottom As Integer = ctrl.Bottom ' If right > maxWidth Then maxWidth = right ' If bottom > maxHeight Then maxHeight = bottom ' Next ' ' Scrollbereich setzen ' Me.AutoScrollMinSize = New Size(maxWidth, maxHeight) ' End Sub 'End Class