VB.net最近控件

发布于 2024-09-01 09:44:36 字数 148 浏览 3 评论 0原文

有没有一种简单的方法可以让控件距离所选控件最近?

我有一个图片框和一些其他移动控件。我想删除距离我的图片框最近的控件。

因此,我必须获取所有控件的位置,并删除位置最接近图片框位置的控件。我不确定如何最好地做到这一点。

Is there an easy way to get the nearest control to a control of choice?

I have a picture box and some other moving controls. I want to delete the nearest control to my picture box.

So I have to get the position of all controls and delete that with the Location nearest to the Location of my picture box. I'm not sure about how to do that the best way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

零度℉ 2024-09-08 09:44:36

如果您的情况中的“最接近”确实意味着“位置最接近我的图片框的位置”,那么最简单的是:

Me.Controls.Remove((From c In Me.Controls.Cast(Of Control)() Order By c.Location.Distance(PictureBox1.Location) Select c).Skip(1).Take(1)(0))

,其中 Distance 在如下模块中定义:

<System.Runtime.CompilerServices.Extension()> _
Public Function Distance(ByVal p1 As Point, ByVal p2 As Point) As Integer
    Return (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)
End Function

If "closest" in your case indeed means "with the Location nearest to the Location of my picture box", then the easiest would be:

Me.Controls.Remove((From c In Me.Controls.Cast(Of Control)() Order By c.Location.Distance(PictureBox1.Location) Select c).Skip(1).Take(1)(0))

, where Distance is defined in a module like this:

<System.Runtime.CompilerServices.Extension()> _
Public Function Distance(ByVal p1 As Point, ByVal p2 As Point) As Integer
    Return (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)
End Function
掌心的温暖 2024-09-08 09:44:36

这是一个完整的示例表单,通过检查提供的控件是否位于相对于基本控件的 8 个区域之一来计算“最接近”。一半的代码是为了模仿您描述的场景而设置的。 MainButton_Click 及其下面是工作的重点。

Option Explicit On
Option Strict On

Public Class Form1
    Private MainPB As PictureBox
    Private OtherPB As List(Of PictureBox)
    Private WithEvents MainButton As Button
    Private Rnd As New Random()
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Setup the form with sample data
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None

        Me.MainButton = New Button()
        Me.MainButton.Text = "Update"
        Me.MainButton.Left = 1
        Me.MainButton.Top = 20
        Me.Controls.Add(Me.MainButton)


        Me.Width = 1000
        Me.Height = 1000
        MainPB = New PictureBox()
        MainPB.BackColor = Color.Red
        MainPB.Width = 100
        MainPB.Height = 100
        MainPB.Left = (Me.Width \ 2) - (MainPB.Width \ 2)
        MainPB.Top = (Me.Height \ 2) - (MainPB.Height \ 2)
        Me.Controls.Add(MainPB)

        Me.OtherPB = New List(Of PictureBox)
        For I = 0 To 50
            Me.OtherPB.Add(New PictureBox())
            With Me.OtherPB(I)
                .BackColor = Color.Transparent
                .BorderStyle = BorderStyle.FixedSingle
                .Width = 50
                .Height = 50
            End With
            SetRandomPbLocation(Me.OtherPB(I))
            Me.Controls.Add(Me.OtherPB(I))
        Next
    End Sub
    Private Sub SetRandomPbLocation(ByVal pb As PictureBox)
        'Just sets a random location for the picture boxes and ensures that it doesn't overlap with the center PB
        Do While True
            pb.Left = Rnd.Next(1, Me.Width - pb.Width)
            pb.Top = Rnd.Next(1, Me.Height - pb.Height)
            If (pb.Right < Me.MainPB.Left OrElse pb.Left > Me.MainPB.Right) AndAlso (pb.Top > Me.MainPB.Bottom OrElse pb.Bottom < Me.MainPB.Top) Then
                Exit Do
            End If
        Loop
    End Sub
    Private Sub MainButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainButton.Click
        'Randomizes the location of the picture boxes
        For Each PB In Me.OtherPB
            SetRandomPbLocation(PB)
        Next
        'Will hold the closest control after the loop
        Dim ClosestPB As Control = Nothing
        Dim ClosestD, TempD As Double
        For Each PB In Me.OtherPB
            'Reset the control's background color
            PB.BackColor = Color.Transparent
            'Calculate the distance
            TempD = GetDistanceBetweenToControls(PB, Me.MainPB)
            If ClosestPB Is Nothing Then 'If this is the first time through the loop then just use this control as the closest
                ClosestPB = PB
                ClosestD = TempD
            ElseIf TempD < ClosestD Then 'Otherwise if this control is closer than the current closest
                ClosestPB = PB
                ClosestD = TempD
            End If
        Next
        'Set the closest controls background color so that we can see it
        ClosestPB.BackColor = Color.Blue
    End Sub
    Private Shared Function GetDistanceBetweenToControls(ByVal controlToCheck As Control, ByVal baseControl As Control) As Double
        If controlToCheck.Bottom < baseControl.Top Then
            If controlToCheck.Right < baseControl.Left Then 'Above and to the left
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Right, controlToCheck.Bottom), baseControl.Location)
            ElseIf controlToCheck.Left > baseControl.Right Then 'above and to the right
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Left, controlToCheck.Bottom), New Point(baseControl.Right, baseControl.Top))
            Else 'Above
                Return baseControl.Top - baseControl.Bottom
            End If
        ElseIf controlToCheck.Top > baseControl.Bottom Then
            If controlToCheck.Right < baseControl.Left Then 'Below and to the left
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Right, controlToCheck.Top), New Point(baseControl.Left, baseControl.Bottom))
            ElseIf controlToCheck.Left > baseControl.Right Then 'Below and to the right
                Return DistanceBetweenTwoPoints(controlToCheck.Location, New Point(baseControl.Right, baseControl.Bottom))
            Else 'Below
                Return controlToCheck.Top - baseControl.Bottom
            End If
        Else
            If controlToCheck.Right < baseControl.Left Then 'Left
                Return baseControl.Left - controlToCheck.Right
            ElseIf controlToCheck.Left > baseControl.Right Then 'Right
                Return controlToCheck.Left - baseControl.Right
            End If
        End If
    End Function
    Private Shared Function DistanceBetweenTwoPoints(ByVal point1 As Point, ByVal point2 As Point) As Double
        'Standard distance formula
        Return Math.Sqrt((Math.Abs(point2.X - point1.X) ^ 2) + (Math.Abs(point2.Y - point1.Y) ^ 2))
    End Function
End Class

Here's an entire sample form that calculates "closest" by checking if the supplied control is in 1 of 8 regions relative to the base control. Half of the code is setup trying to mimic the scenario you described. The MainButton_Click and below is the meat of the work.

Option Explicit On
Option Strict On

Public Class Form1
    Private MainPB As PictureBox
    Private OtherPB As List(Of PictureBox)
    Private WithEvents MainButton As Button
    Private Rnd As New Random()
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Setup the form with sample data
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None

        Me.MainButton = New Button()
        Me.MainButton.Text = "Update"
        Me.MainButton.Left = 1
        Me.MainButton.Top = 20
        Me.Controls.Add(Me.MainButton)


        Me.Width = 1000
        Me.Height = 1000
        MainPB = New PictureBox()
        MainPB.BackColor = Color.Red
        MainPB.Width = 100
        MainPB.Height = 100
        MainPB.Left = (Me.Width \ 2) - (MainPB.Width \ 2)
        MainPB.Top = (Me.Height \ 2) - (MainPB.Height \ 2)
        Me.Controls.Add(MainPB)

        Me.OtherPB = New List(Of PictureBox)
        For I = 0 To 50
            Me.OtherPB.Add(New PictureBox())
            With Me.OtherPB(I)
                .BackColor = Color.Transparent
                .BorderStyle = BorderStyle.FixedSingle
                .Width = 50
                .Height = 50
            End With
            SetRandomPbLocation(Me.OtherPB(I))
            Me.Controls.Add(Me.OtherPB(I))
        Next
    End Sub
    Private Sub SetRandomPbLocation(ByVal pb As PictureBox)
        'Just sets a random location for the picture boxes and ensures that it doesn't overlap with the center PB
        Do While True
            pb.Left = Rnd.Next(1, Me.Width - pb.Width)
            pb.Top = Rnd.Next(1, Me.Height - pb.Height)
            If (pb.Right < Me.MainPB.Left OrElse pb.Left > Me.MainPB.Right) AndAlso (pb.Top > Me.MainPB.Bottom OrElse pb.Bottom < Me.MainPB.Top) Then
                Exit Do
            End If
        Loop
    End Sub
    Private Sub MainButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainButton.Click
        'Randomizes the location of the picture boxes
        For Each PB In Me.OtherPB
            SetRandomPbLocation(PB)
        Next
        'Will hold the closest control after the loop
        Dim ClosestPB As Control = Nothing
        Dim ClosestD, TempD As Double
        For Each PB In Me.OtherPB
            'Reset the control's background color
            PB.BackColor = Color.Transparent
            'Calculate the distance
            TempD = GetDistanceBetweenToControls(PB, Me.MainPB)
            If ClosestPB Is Nothing Then 'If this is the first time through the loop then just use this control as the closest
                ClosestPB = PB
                ClosestD = TempD
            ElseIf TempD < ClosestD Then 'Otherwise if this control is closer than the current closest
                ClosestPB = PB
                ClosestD = TempD
            End If
        Next
        'Set the closest controls background color so that we can see it
        ClosestPB.BackColor = Color.Blue
    End Sub
    Private Shared Function GetDistanceBetweenToControls(ByVal controlToCheck As Control, ByVal baseControl As Control) As Double
        If controlToCheck.Bottom < baseControl.Top Then
            If controlToCheck.Right < baseControl.Left Then 'Above and to the left
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Right, controlToCheck.Bottom), baseControl.Location)
            ElseIf controlToCheck.Left > baseControl.Right Then 'above and to the right
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Left, controlToCheck.Bottom), New Point(baseControl.Right, baseControl.Top))
            Else 'Above
                Return baseControl.Top - baseControl.Bottom
            End If
        ElseIf controlToCheck.Top > baseControl.Bottom Then
            If controlToCheck.Right < baseControl.Left Then 'Below and to the left
                Return DistanceBetweenTwoPoints(New Point(controlToCheck.Right, controlToCheck.Top), New Point(baseControl.Left, baseControl.Bottom))
            ElseIf controlToCheck.Left > baseControl.Right Then 'Below and to the right
                Return DistanceBetweenTwoPoints(controlToCheck.Location, New Point(baseControl.Right, baseControl.Bottom))
            Else 'Below
                Return controlToCheck.Top - baseControl.Bottom
            End If
        Else
            If controlToCheck.Right < baseControl.Left Then 'Left
                Return baseControl.Left - controlToCheck.Right
            ElseIf controlToCheck.Left > baseControl.Right Then 'Right
                Return controlToCheck.Left - baseControl.Right
            End If
        End If
    End Function
    Private Shared Function DistanceBetweenTwoPoints(ByVal point1 As Point, ByVal point2 As Point) As Double
        'Standard distance formula
        Return Math.Sqrt((Math.Abs(point2.X - point1.X) ^ 2) + (Math.Abs(point2.Y - point1.Y) ^ 2))
    End Function
End Class
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文