Я думаю, что это будет хорошо работать (cellSize
- это «разрешение», с которым элемент управления «привязывается» при условии, что каждая ячейка является квадратной).
Предварительные условия: вам нужно иметь PictureBox
(или какой-либо другой элемент управления), который вы хотите перемещать в своей Форме. Поместите приведенный ниже пример кода в код вашей формы и присоедините события MouseDown
, MouseMove
и MouseUp
этого элемента управления к этим обработчикам событий. Вы можете прикрепить события, используя сетку свойств (нажмите кнопку событий, выберите событие и используйте поле со списком, чтобы выбрать соответствующий обработчик событий).
VB.NET:
Private Sub SetControlPosition(ByVal control As Control, ByVal targetPoint As Point, ByVal cellSize As Integer)
Dim roundedLocation As New Point(CInt((Math.Round(CSng(targetPoint.X) / cellSize) * cellSize)), CInt((Math.Round(CSng(targetPoint.Y) / cellSize) * cellSize)))
control.Location = roundedLocation
End Sub
Если вы хотите, чтобы местоположение элемента управления привязывалось к некоторым заранее определенным местоположениям, вы можете сделать это вместо этого (_allowedLocations
определяет два разрешенных местоположения; x=50, y=50
и x=500, y=500
):
Private _allowedLocations As Point() = {New Point(50, 50), New Point(500, 500), New Point(700, 100)}
Private Sub SetControlPosition(ByVal control As Control, ByVal targetPoint As Point, ByVal cellSize As Integer)
Dim shortestDistance As Integer = Integer.MaxValue
Dim nearestLocationIndex As Integer = -1
For i As Integer = 0 To _allowedLocations.Length - 1
Dim width As Integer = targetPoint.X - _allowedLocations(i).X
Dim height As Integer = targetPoint.Y - _allowedLocations(i).Y
Dim distance As Integer = CInt(Math.Sqrt(Math.Pow(width, 2) + Math.Pow(height, 2)))
If distance < shortestDistance Then
shortestDistance = distance
nearestLocationIndex = i
End If
Next
control.Location = _allowedLocations(nearestLocationIndex)
End Sub
Пример кода, вызывающего метод (включая перемещение элемента управления с помощью мыши):
Private _mouseDownLocation As Point = Point.Empty
Private Sub PictureBox_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
_mouseDownLocation = e.Location
End If
End Sub
Private Sub PictureBox_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
Dim target As Control = DirectCast(sender, Control)
target.Location = New Point(target.Location.X + e.Location.X - _mouseDownLocation.X, target.Location.Y + e.Location.Y - _mouseDownLocation.Y)
End If
End Sub
Private Sub PictureBox_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
Dim target As Control = DirectCast(sender, Control)
' Snap the control in place, to nearest 100x100 corner '
SetControlPosition(target, target.Location, 100)
End If
End Sub
Метод SetControlPosition в C # (в качестве дополнительного бонуса):
private void SetControlPosition(Control control, Point targetPoint, int cellSize)
{
Point roundedLocation = new Point(
(int)(Math.Round((float)targetPoint.X / cellSize) * cellSize),
(int)(Math.Round((float)targetPoint.Y / cellSize) * cellSize)
);
control.Location = roundedLocation;
}