拖放groupbox / picturebox与textbox vb.net

时间:2018-07-24 19:26:41

标签: vb.net drag-and-drop

仅仅是我还是对boxbox / picturebox和textbox的拖放不同?我有此拖放代码,可让我调整控件的大小和拖放。但是,每当我尝试使用groupbox / picturebox时,该控件就会反复闪烁并且不会移动,并且鼠标光标停留在父控件中。动态创建的文本框不会发生这种情况。我需要为groupbox / picturebox启用某些功能吗?

拖放dll

#Region "     class library"

#Region "     imports"

Imports System.Windows.Forms
Imports System.Drawing
Imports System.Runtime.InteropServices

#End Region

Public Class controlHandler

#Region "     global variables"

Private horizontalMidPoint As Integer
Private verticalMidPoint As Integer
Private locations() As Point
Private width As Control
Private height As Control
Private dpiX As Integer
Private dpiY As Integer
Private myControl As Control
Private controlType As String

Public Structure boundControl
    Public mControl As Control
    Public mParent As Control
    Public Sub New(ByVal parent As Control, ByVal control As Control)
        mParent = parent
        mControl = control
    End Sub
End Structure

Private activeControl As Control = Nothing
Private activeControlParent As Control = Nothing

#End Region

#Region "     properties"

Private _boundControls As New List(Of boundControl)
Public ReadOnly Property boundControls As List(Of boundControl)
    Get
        Return _boundControls
    End Get
End Property

Public Property boundingRectangle As Rectangle

Private _canDeselect As Boolean = True
Public Property canDeselect As Boolean
    Get
        Return _canDeselect
    End Get
    Set(ByVal value As Boolean)
        _canDeselect = value
    End Set
End Property

#End Region

#Region "    WidthHeightSetter"
Public Sub setWidthHeightBoxes(w As Control, h As Control, x As Integer, y As Integer, bound As boundControl)
    width = w
    height = h
    myControl = bound.mControl
    dpiX = x
    dpiY = y
    AddHandler myControl.SizeChanged, AddressOf myControl_ResizeHandler
End Sub
#End Region

#Region "    Resize Handler"
Private Sub myControl_ResizeHandler(ByVal sender As Object, ByVal e As EventArgs)
    Dim w As Double
    Dim h As Double

    w = (Convert.ToDouble(myControl.Size.Width()) / dpiX) / 2
    h = (Convert.ToDouble(myControl.Size.Height()) / dpiY) / 2


    width.Text = FormatNumber(CDbl(Convert.ToString(w)), 2)
    height.Text = FormatNumber(CDbl(Convert.ToString(h)), 2)

    'Debug.Print(FormatNumber(CDbl(Convert.ToString(w)), 2))
    'Debug.Print(FormatNumber(CDbl(Convert.ToString(h)), 2))
End Sub
#End Region

#Region "    controlType getter/setter"
Public Sub setControlType(s As String)
    controlType = s
End Sub

Public Function getControlType() As String
    Return controlType
End Function
#End Region
#Region "     initialize"

Public Sub bindControls()
    For x As Integer = 0 To _boundControls.Count - 1
        Dim ctrl As Control = _boundControls(x).mControl
        AddHandler ctrl.MouseDown, AddressOf mControl_mousedown
        AddHandler ctrl.Paint, AddressOf mControl_Paint
        AddHandler ctrl.Resize, AddressOf mControl_Resize
        AddHandler ctrl.Move, AddressOf mControl_Move
        Dim parent As Control = _boundControls(x).mParent
    Next
End Sub

#End Region

#Region "     drag handles"

Public Sub deselectAll()
    If activeControl IsNot Nothing And canDeselect Then
        activeControl = Nothing
        boundingRectangle = Nothing
        For x As Integer = 0 To 8
            pb(x).Dispose()
        Next
        activeControlParent.Invalidate()
    End If
End Sub

Private pb(8) As PictureBox

Private Sub addDragHandles()
    Dim sizeCursor() As Cursor = {Cursors.SizeNWSE, Cursors.SizeNS, Cursors.SizeNESW, Cursors.SizeWE, _
    Cursors.SizeNWSE, Cursors.SizeNS, Cursors.SizeNESW, Cursors.SizeWE}

    Dim smConstants() As Integer = {HTTOPLEFT, HTTOP, HTTOPRIGHT, HTRIGHT, HTBOTTOMRIGHT, _
        HTBOTTOM, HTBOTTOMLEFT, HTLEFT}

    For x As Integer = 1 To 8
        pb(x - 1) = New PictureBox
        With pb(x - 1)
            .BackColor = Color.White
            .Size = New Size(6, 6)
            .BorderStyle = BorderStyle.FixedSingle
            .Location = locations(x - 1)
            .Cursor = sizeCursor(x - 1)
            .Tag = smConstants(x - 1)
            activeControlParent.Controls.Add(pb(x - 1))
            .BringToFront()
            AddHandler .MouseDown, AddressOf pbsMouseDown
            AddHandler .MouseMove, AddressOf pbsMouseMove
        End With
    Next
    pb(8) = New PictureBox
    pb(8).Size = New Size(15, 15)
    pb(8).BorderStyle = BorderStyle.None
    pb(8).Location = locations(8)
    pb(8).Cursor = Cursors.SizeAll
    pb(8).Image = My.Resources.move
    activeControlParent.Controls.Add(pb(8))
    pb(8).BringToFront()
    AddHandler pb(8).MouseDown, AddressOf move_mousedown
    AddHandler pb(8).MouseMove, AddressOf move_mousemove
End Sub

#End Region

#Region "     resize handles"

Private mouseOnHandle As Boolean = False

Private Sub pbsMouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    mouseOnHandle = True
End Sub

Private Sub pbsMouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    If mouseOnHandle Then
        ReleaseCapture()
        SendMessage(activeControl.Handle, WM_NCLBUTTONDOWN, CInt(DirectCast(sender, PictureBox).Tag), 0)
        If GetCapture = 0 Then mouseOnHandle = False
        Application.DoEvents()
    End If
End Sub

#Region "     move resize handles"

Private Sub paintresize()

    If activeControl IsNot Nothing Then
        horizontalMidPoint = CInt(activeControl.Left + (activeControl.Width / 2))
        verticalMidPoint = CInt(activeControl.Top + (activeControl.Height / 2))

        locations = New Point() _
        {New Point(activeControl.Left - 3, activeControl.Top - 3), New Point(horizontalMidPoint - 3, activeControl.Top - 3),
        New Point(activeControl.Right - 2, activeControl.Top - 3), New Point(activeControl.Right - 2, verticalMidPoint - 3),
        New Point(activeControl.Right - 2, activeControl.Bottom - 2), New Point(horizontalMidPoint - 3, activeControl.Bottom - 2),
        New Point(activeControl.Left - 3, activeControl.Bottom - 2), New Point(activeControl.Left - 3, verticalMidPoint - 3),
        New Point(activeControl.Left + 9, activeControl.Top - 10)}

        For x As Integer = 0 To 8
            pb(x).Location = locations(x)
        Next
    End If

End Sub

#End Region

#End Region

#Region "     move handle"

Private mouseOnMove As Boolean = False

Private Sub move_mousedown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    mouseOnMove = True
End Sub

Private Sub move_mousemove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
    If mouseOnMove Then
        ReleaseCapture()
        SendMessage(activeControl.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0)
        If GetCapture = 0 Then
            mouseOnMove = False
            For x As Integer = 0 To 8
                pb(x).BringToFront()
            Next
        End If
    End If
End Sub

#End Region

#Region "     control eventHandlers"

Private Sub mControl_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)

    Application.DoEvents()

    If sender Is activeControl Then

        drawBoundingRectangle()

        paintresize()

    End If

End Sub

Private Sub mControl_Resize(ByVal sender As Object, ByVal e As System.EventArgs)
    If activeControl IsNot Nothing Then
        activeControl.Invalidate()
        Application.DoEvents()
        drawBoundingRectangle()
        paintresize()
    End If


End Sub

Private Sub mControl_Move()
    If activeControl IsNot Nothing Then
        activeControl.Invalidate()
        Application.DoEvents()
        drawBoundingRectangle()
        paintresize()
    End If

End Sub



Private Sub mControl_mousedown(ByVal sender As Object, ByVal e As System.EventArgs)

    If activeControlParent IsNot Nothing Then activeControlParent.Invalidate()

    Dim newCtrl As Control = DirectCast(sender, Control)

    horizontalMidPoint = CInt(newCtrl.Left + (newCtrl.Width / 2))
    verticalMidPoint = CInt(newCtrl.Top + (newCtrl.Height / 2))

    locations = New Point() _
    {New Point(newCtrl.Left - 3, newCtrl.Top - 3), New Point(horizontalMidPoint - 3, newCtrl.Top - 3), _
    New Point(newCtrl.Right - 2, newCtrl.Top - 3), New Point(newCtrl.Right - 2, verticalMidPoint - 3), _
    New Point(newCtrl.Right - 2, newCtrl.Bottom - 2), New Point(horizontalMidPoint - 3, newCtrl.Bottom - 2), _
    New Point(newCtrl.Left - 3, newCtrl.Bottom - 2), New Point(newCtrl.Left - 3, verticalMidPoint - 3), _
    New Point(newCtrl.Left + 9, newCtrl.Top - 10)}

    If activeControl IsNot Nothing Then
        For x As Integer = 0 To 8
            pb(x).Dispose()
        Next
    End If
    activeControl = newCtrl
    For x As Integer = 0 To _boundControls.Count - 1
        If _boundControls(x).mControl Is activeControl Then
            activeControlParent = _boundControls(x).mParent
            Exit For
        End If
    Next

    drawBoundingRectangle()

    addDragHandles()

End Sub

#End Region

#Region "     set activeControl bounding rectangle"

Private Sub drawBoundingRectangle()
    If activeControl IsNot Nothing Then
        Dim r As Rectangle = activeControl.Bounds
        r.Inflate(1, 1)
        boundingRectangle = r
        activeControlParent.Invalidate()

    End If
End Sub

#End Region

#Region " Functions and Constants "

<DllImport("user32.dll")> _
Public Shared Function ReleaseCapture() As Boolean
End Function

<DllImport("user32.dll")> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function

Public Declare Function GetCapture Lib "user32" Alias "GetCapture" () As Integer

Private Const WM_NCLBUTTONDOWN As Integer = &HA1
Private Const HTBORDER As Integer = 18
Private Const HTBOTTOM As Integer = 15
Private Const HTBOTTOMLEFT As Integer = 16
Private Const HTBOTTOMRIGHT As Integer = 17
Private Const HTCAPTION As Integer = 2
Private Const HTLEFT As Integer = 10
Private Const HTRIGHT As Integer = 11
Private Const HTTOP As Integer = 12
Private Const HTTOPLEFT As Integer = 13
Private Const HTTOPRIGHT As Integer = 14

#End Region

End Class

#End Region

实施方式

Dim worker As New controlHandler
    Dim textBoxBoundControl As New controlHandler.boundControl(Panel2, DragAndDropGroupBox)
    worker.setWidthHeightBoxes(nameWidth, nameHeight, dpiX, dpiY, textBoxBoundControl)
    Dim TextSizeChangeHandler As New TextSizeChangeHandler(labelSizeWidth, labelSizeHeight, DragAndDropGroupBox, dpiX, dpiY)

    worker.boundControls.Add(textBoxBoundControl)
    worker.bindControls()

编辑: 问题似乎在于groupbox。我只是尝试单独放置一个图片框,然后将其拖放就好了。但是,即使组框的唯一父级是标签页,我仍然无法将其拖放。当图片框是分组框的子级时,图片框会出现问题

编辑2: 似乎是具有图像源的图片框的问题。我只是尝试了一个空白的图片框,它起作用了。

1 个答案:

答案 0 :(得分:0)

似乎将背景颜色从透明更改为白色或其他某种颜色可以解决此问题。这似乎更像是一个“ hack”,但是到目前为止,我将使用它直到出现更好的解决方案。