仅仅是我还是对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: 似乎是具有图像源的图片框的问题。我只是尝试了一个空白的图片框,它起作用了。
答案 0 :(得分:0)
似乎将背景颜色从透明更改为白色或其他某种颜色可以解决此问题。这似乎更像是一个“ hack”,但是到目前为止,我将使用它直到出现更好的解决方案。