在运行时拖动

时间:2009-07-16 11:57:01

标签: vb.net winforms

用户可以选择在表单周围拖动多个图片框。当他放开鼠标时,图片框将在表单上占据一个新位置。由于stackoverflow社区,我已经成功完成了这项工作。

我想实现以下内容:

在mouseup上,如果图片框位置在某个数量内可能是50或100(我不知道VB.net使用的是什么单位),我希望它可以完全放在一个定义的位置。有点像你在雅虎游戏中玩跳棋,你不必将这件作品恰好放在广场上。

请帮我解决vb.net中的解决方案

1 个答案:

答案 0 :(得分:2)

这会很好用,我认为(cellSize是控件将“捕捉”的“分辨率”,假设每个单元都是方形的。)

先决条件:您需要在表单上移动PictureBox(或其他一些控件)。将示例代码放在表单的代码中,并将该控件的MouseDownMouseMoveMouseUp事件附加到这些事件处理程序。您可以使用属性网格附加事件(单击事件按钮,选择事件,然后使用组合框选择相应的事件处理程序)。

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=50x=500, y=500):< / p>

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

C#中的SetControlPosition方法(作为额外奖励):

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;
}