Drag and Drop like vista's explorer

sarthemaker

Active member
Joined
Sep 4, 2009
Messages
36
Programming Experience
5-10
Is there a way to drag and drop items like vista where it creates a "ghost" of the icon and text at the cursor position? Like a slightly transparent copy of the item being dragged with the mouse until it is dropped?

Is this possible in vb.net?
 
First up, please post in the most appropriate forum for the topic of your thread rather than just the first one you come to. Thread moved.

As for the question, there's is no strictly managed way to do it. You'll need to use unamanged (i.e. non-.NET) code; specifcally the Windows API. Here are a couple of links that should be of help:

CodeProject: Dragging tree nodes in C#. Free source code and programming help
CodeProject: Drag and Drop Treeview control. Free source code and programming help

The code is C# but the principles are exactly the same for VB. If you can't write the equivalent VB code yourself then you could try one of the many online converters. They're not exactly 100% reliable though. You could also try Instant VB, which is a standalone tool with very high accuracy. If you're not prepared to pay then the trial version should be enough to get you through this project at least.
 
I converted the first code to vb.net using an online convert, and I tried to make it work for my file explorer, but I can't get it to work.. Because I am not using a listview, or treeview. I am using a flowlayoutpanel so I can customize how the items look. So I'm not sure how to make this code work for my items.. I have tried this:

VB.NET:
 Private Sub Tile_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs)
        ' Get drag node and select it

        Dim dragTile = DirectCast(e.Item, PictureBox)
        Dim dragNode = tilesSelIndex.Peek

        ' Reset image list used for drag image

        ' Create new bitmap

        ' This bitmap will contain the tree node image to be dragged

        Dim bmp As New Bitmap(80, 80)

        ' Get graphics from bitmap

        Dim gfx As Graphics = Graphics.FromImage(bmp)

        ' Draw node icon into the bitmap

        gfx.DrawImage(My.Resources._Default1, 0, 0)

        ' Draw node label into bitmap

        gfx.DrawString("Works", New Font("arial", 9), New SolidBrush(Color.Black), CSng(0), 1.0F)

        ' Get mouse position in client coordinates

        Dim p As Point = Me.ViewerTile.PointToClient(Control.MousePosition)

        ' Compute delta between mouse position and node bounds

        Dim dx As Integer = p.X - tilesSelIndex(0).Bounds.Left
        Dim dy As Integer = p.Y - tilesSelIndex(0).Bounds.Top

        ' Begin dragging image

        If DragHelper.ImageList_BeginDrag(ViewerTile.Handle, 0, dx, dy) Then
            ' Begin dragging

            ViewerTile.DoDragDrop(bmp, DragDropEffects.Move)
            ' End dragging image

            DragHelper.ImageList_EndDrag()

        End If
    End Sub

    Private Sub treeView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
        ' Compute drag position and move image

        Dim formP As Point = Me.PointToClient(New Point(e.X, e.Y))

        DragHelper.ImageList_DragMove(formP.X - ViewerTile.Left, formP.Y - ViewerTile.Top)
    End Sub
But this does not work, is there another way to drag a control other than a treeview node?
 
Not to change the topic here, but what I would like to know how to do is when a file/folder from explorer itself is dragged onto my .Net form I'd like my .Net app to show the same image as explorer during the entire process, I have yet to figure that one out.
 
Let me first say that I've never actually done this myself. I haven't even done much reading on the topic but what I have read indicates that it's not trivial. I knew that there was some info on The Code Project so I searched there and found those last two links. I just Googled ghost image drag drop .net and came up with a couple more links:

CodeProject: Windows Explorer style ghost drag image in a C# application. Free source code and programming help
Anything's Possible : Shell Style Drag and Drop in .NET (WPF and WinForms)

I can't provide any specific advice beyond that.
 
Not to change the topic here, but what I would like to know how to do is when a file/folder from explorer itself is dragged onto my .Net form I'd like my .Net app to show the same image as explorer during the entire process, I have yet to figure that one out.
Download the attachment from CodeProject: Windows Explorer style ghost drag image in a C# application. Free source code and programming help in ShellUtils/Release folder there's a ShellUtils.dll you can reference. The library is using IDragSourceHelper and IDropTargetHelper interfaces. Here's some sample code I used when testing out various of these methods a while back, it's just a form with a ImageList and a ListView (assigned ImageList, AllowDrop, Dock=Fill)
VB.NET:
Public Class Form2
    Private _dropHelper As ShellUtils.DropTarget

    Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        _dropHelper = New ShellUtils.DropTarget(ListView1.Handle)
    End Sub



    Private Sub ListView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragDrop
        _dropHelper.Drop(PointToClient(MousePosition), e.Effect, e.Data)
        Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
        For Each file As String In files
            Dim ext As String = IO.Path.GetExtension(file)
            If Not ImageList1.Images.ContainsKey(ext) Then
                ImageList1.Images.Add(ext, Icon.ExtractAssociatedIcon(file))
            End If
            ListView1.Items.Add(file, ext)
        Next
    End Sub

    Private Sub ListView1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = e.AllowedEffect
            _dropHelper.DragEnter(ListView1.PointToClient(New Point(e.X, e.Y)), e.Effect, e.Data)
        End If
    End Sub

    Private Sub ListView1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.DragLeave
        _dropHelper.DragLeave()
    End Sub

    Private Sub ListView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragOver
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = e.AllowedEffect
            Dim pt As Point = ListView1.PointToClient(New Point(e.X, e.Y))
            _dropHelper.DragOver(pt, e.Effect)
            _dropHelper.Show(True)
        End If
    End Sub

    Private Sub ListView1_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles ListView1.ItemDrag
        If e.Button = Windows.Forms.MouseButtons.Left Then
            If ListView1.SelectedItems.Count > 0 Then
                Dim files As New Specialized.StringCollection
                For Each lvi As ListViewItem In ListView1.SelectedItems
                    files.Add(lvi.Text)
                Next
                Dim data As New ShellUtils.DataObjectEx
                data.SetFileDropList(files)
                ShellUtils.DragSource.DoDragDrop(data, ListView1, DragDropEffects.Copy Or DragDropEffects.Move, PointToClient(MousePosition))

            End If
        End If
    End Sub


  
End Class
 
I was testing the above from .Net 4 and ran into some troubles. The library is very old (compiled .Net 1.1) and may be mixed-mode, adding this to configuration section of app.config fixed that:
HTML:
<startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
Then there was LoaderLock exception no matter what, disabling that can be done in Debug>Exceptions>MDA>LoaderLock (uncheck Thrown).
After this drag-drop worked as advertised.
I tried to recompile the library without success, if there is a newer library somewhere that makes this functionality equally easy to add to a .Net app do post the link.
Found a three part article with C# sources here Shell Style Drag and Drop in .NET (WPF and WinForms), compiled and tested, but was unable to make it work when dragging to Windows Explorer.
 
Back
Top