【问题标题】:Drag and drop for groupbox/picturebox vs textbox vb.net拖放组框/图片框与文本框 vb.net
【发布时间】:2018-07-24 19:26:40
【问题描述】:

只是我还是组框/图片框与文本框的拖放不同?我有这个拖放代码,允许我调整大小和拖放控件。但是,每当我尝试使用 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: 似乎是具有图像源的图片框的问题。我刚刚尝试了一个空白的图片框,它可以工作。

【问题讨论】:

  • SizeModePictureBox 是什么?
  • 拉伸。但是,我也尝试了正常,并且效果很好,所以我认为这不是 SizeMode 的问题

标签: vb.net drag-and-drop


【解决方案1】:

似乎将背景颜色从透明更改为白色或其他颜色可以解决此问题。这看起来更像是一个“黑客”,但现在,我将使用它,直到出现更好的解决方案。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 2013-07-14
    • 2013-11-05
    • 2013-10-25
    • 2010-11-07
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多