对齐网格 MDI 子窗体 vb.net
snap to grid MDI child forms vb.net
我正在 Visual Basic 中开发一个模块化仪表板,它从一个空容器开始,我无法添加模块来填充它。
父窗体是一个 MDI 容器,每个模块都是一个具有固定大小的子 MDI 窗体。
我想在用户创建新子窗体时以及将其中一个子窗体移动到容器内时(就像它们被磁化到该网格一样)将所有子窗体对齐到一个网格。
我该怎么做?谢谢
如果我很清楚你需要这样的东西:
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
按照下面的评论进行更改(如果需要):
这是基于与 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
我正在 Visual Basic 中开发一个模块化仪表板,它从一个空容器开始,我无法添加模块来填充它。
父窗体是一个 MDI 容器,每个模块都是一个具有固定大小的子 MDI 窗体。
我想在用户创建新子窗体时以及将其中一个子窗体移动到容器内时(就像它们被磁化到该网格一样)将所有子窗体对齐到一个网格。
我该怎么做?谢谢
如果我很清楚你需要这样的东西:
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
按照下面的评论进行更改(如果需要):
这是基于与 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