привязка к сетке дочерних форм MDI vb.net - PullRequest
0 голосов
/ 06 августа 2020
• 1000 Форма MDI с фиксированным размером.

Я хотел бы привязать всю эту дочернюю форму к сетке, когда пользователь создает новую и перемещает одну из них внутри контейнера (например, они намагничиваются для эту сетку).

Как я могу это сделать? Спасибо

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

Если я хорошо понимаю, вам нужно что-то вроде этого:

    Private Class ImaginaryGrid

    ' You can change Columns and Rows as you want
    Shared Rows As Integer = 3
    Shared Cols As Integer = 3

    Private Shared Function SnapToGrid(target As Form) As Point

        Dim AllW As Integer = Screen.PrimaryScreen.WorkingArea.Width
        Dim AllH As Integer = Screen.PrimaryScreen.WorkingArea.Height

        Dim parent = target.MdiParent
        If parent IsNot Nothing Then
            AllW = target.MdiParent.ClientSize.Width
            AllH = target.MdiParent.ClientSize.Height
        End If

        Dim currentPoint As Point = target.Location

        Dim stepW As Integer = CInt(AllW / Cols)
        Dim stepH As Integer = CInt(AllH / Rows)

        Dim targetCol As Integer = CInt(currentPoint.X \ stepW)
        Dim targetRow As Integer = CInt(currentPoint.Y \ stepH)

        Dim newX As Integer = targetCol * stepW
        Dim newY As Integer = targetRow * stepH

        target.Location = New Point(newX, newY)
        target.Width = stepW
        target.Height = stepH

    End Function

    Shared Sub AttachFormToStayInGrid(frm As Form)
        AddHandler frm.ResizeEnd, Sub()
                                      SnapToGrid(frm)
                                  End Sub
        SnapToGrid(frm)
    End Sub

End Class

Использование:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    ImaginaryGrid.AttachFormToStayInGrid(Me)
End Sub

Внесите изменения (при необходимости), как показано в комментариях ниже:

1 голос
/ 06 августа 2020

Вот усиленная версия, основанная на той же идее, что и предложение G3nt_M3caj:

введите описание изображения здесь

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ImaginaryGrid.Client = Me.Controls.OfType(Of MdiClient).FirstOrDefault
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim frm As New Form
        ImaginaryGrid.AttachFormToStayInGrid(frm)
    End Sub

    Private Class ImaginaryGrid

        Public Shared WithEvents Client As MdiClient

        Public Shared FixedChildSize As New Size(250, 150)

        Private Shared Function SnapToGrid(target As Form) As Rectangle
            Dim colX As Integer = target.Location.X / FixedChildSize.Width
            Dim colY As Integer = target.Location.Y / FixedChildSize.Height
            Dim newX As Integer = colX * FixedChildSize.Width
            Dim newY As Integer = colY * FixedChildSize.Height

            Return New Rectangle(New Point(newX, newY), FixedChildSize)
        End Function

        Shared Sub AttachFormToStayInGrid(frm As Form)
            frm.Size = FixedChildSize
            frm.FormBorderStyle = FormBorderStyle.FixedSingle
            frm.MdiParent = Client.Parent
            frm.Show()
            SnapChild(frm)

            AddHandler frm.ResizeEnd, Sub()
                                          SnapChild(frm)
                                      End Sub
            AddHandler frm.LocationChanged, Sub()
                                                If frm.WindowState = FormWindowState.Normal Then
                                                    snapRectangle = SnapToGrid(frm)
                                                    Client.Refresh()
                                                End If
                                            End Sub
        End Sub

        Private Shared Sub SnapChild(ByVal frm As Form)
            If frm.WindowState = FormWindowState.Normal Then
                Dim rc As Rectangle = SnapToGrid(frm)
                frm.Bounds = rc
                snapRectangle = Nothing
                Client.Refresh()
            End If
        End Sub

        Private Shared snapRectangle? As Rectangle

        Private Shared Sub Client_Paint(sender As Object, e As PaintEventArgs) Handles Client.Paint
            If snapRectangle.HasValue Then
                e.Graphics.DrawRectangle(Pens.Black, snapRectangle)
            End If
        End Sub

    End Class

End Class
...