Introduction
Working with the winforms native drag&drop, I happened to have to give the user the perception of what's dragging. Looking for a variety of articles, I came across various drag helpers, many of which use retrieved to specific Windows API, as illustrated, for example, in this article.
The main problem was to create multiple image files.
Background
To create this effect, I used a transparent form to draw the controls to be dragged, absolutely positioned respect to the area of the form itself. For multiple selection, I use the standard Mouse shell selection, or click on control to single Drag.
The drawExtension
module in the project, is only for border effects on control, but is not binding on the project itself. For controls drawing, refer to the namespace Graphics
methods.
Using the Code
If buttonOnControlIsPressed Then
buttonOnControlIsPressed = False
Dim splacement As Integer = 5
initialSplacement = New Point(e.X + splacement, e.Y + splacement)
frmD = New frmDrag With {.Location = Me.PointToScreen(initialSplacement), _
.Size = Me.ClientSize, .Visible = False, .TopMost = True}
frmDLocationBeforeDrag = frmD.Location
controlsToDrag = New List(Of Control)
For Each c As Control In Me.Controls
If c.Tag("selected") = True Then controlsToDrag.Add(c)
Next
For Each c As Control In controlsToDrag
Dim img As Image = getImageFromControl(c)
frmD.Controls.Add(New PictureBox With _
{.Size = img.Size, .Image = img, .Location = New Point(c.Location.X, c.Location.Y)})
Next
startPointBeforeControlDrag = Me.PointToClient(MousePosition)
If Me.DoDragDrop(Me, DragDropEffects.All) = DragDropEffects.None Then
controlsToDrag.ForEach(Sub(x)
x.Tag("selected") = False
x.DrawBorder()
End Sub)
frmD.Close()
End If
End If
Building of DragForm
is done when drag starts on any controls in form. All necessary events are initialized to the added control event in Main Form, so you can perform the same effect on runtime added controls
Private Sub frmMain_ControlAdded(sender As Object, e As ControlEventArgs) Handles Me.ControlAdded
Dim htCustomProperty As New Hashtable
htCustomProperty("selected") = False
e.Control.Tag = htCustomProperty
AddHandler e.Control.MouseDown, AddressOf _controlsMouseDown
AddHandler e.Control.MouseUp, AddressOf _controlsMouseUp
AddHandler e.Control.MouseMove, AddressOf _controlMouseMove
e.Control.Cursor = Cursors.SizeAll
allControls.Add(e.Control)
End Sub
Points of Interest
The technique of a transparent and opaque additional form is also useful to solve the problem to create form with shadow.