In old vb6.0 it was easy to highlight the target item, where to drop those dragged rows.

Private Sub listView_OLEDragOver(Data As MSComctlLib.DataObject, Effect As Long, Button As Integer, Shift As Integer, x As Single, y As Single, State As Integer)
Set listView.DropHighlight = listView.HitTest(x, y)

I have been Googling all day to find out, how to do that in VB.NET (
and I wasn't the only one without an proper answer).

You can get the item to drop to in VB.NET:

Private Sub ListView_DragDrop(ByVal sender As Object, ByVal _
    e As System.Windows.Forms.DragEventArgs) Handles _
    ListView.DragDrop

Dim lvw As ListView = DirectCast(sender, ListView)
        Dim dragged_items As List(Of ListViewItem) = _
            e.Data.GetData("System.Collections.Generic.List(Of " & _
                "System.Windows.Forms.ListViewItem)")

        Dim pt As Point = lvw.PointToClient(New Point(e.X, e.Y))
        Dim lvi As ListViewItem = lvw.GetItemAt(pt.X, pt.Y)
        Dim index As Integer
        If lvi IsNot Nothing Then
            index = lvi.Index
        End If

        Dim hti As ListViewHitTestInfo = lvw.HitTest(pt.X, pt.Y)
If (hti.Item Is Nothing) Then Return
        Dim item As ListViewItem = hti.Item

Now we got the index and item, where to drop. But then what? One possibility to do the HighLight is change the ListViews state to "LVIS_DROPHILITED" by sending Windows message "SendMessageA(lvw.Handle, LVIS_DROPHILITED, 0, 0)". But when is the right time to do that (DragEnter or DragDrop event) and what are the right parameters? Didn't succeed on that yet. I appreciate any kind of help???

Recommended Answers

All 4 Replies

Member Avatar for Unhnd_Exception

If your just trying to show the user where they are about to drop an item then you can use the listview's insertion mark for that.

I think I copied and pasted this code along time ago from an example off the MSDN site.

Private Sub ListView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragOver

    ' Retrieve the client coordinates of the mouse pointer.
    Dim targetPoint As Point = ListView1.PointToClient(New Point(e.X, e.Y))

    ' Retrieve the index of the item closest to the mouse pointer.
    Dim targetIndex As Integer = _
     ListView1.InsertionMark.NearestIndex(targetPoint)

        ' Confirm that the mouse pointer is not over the dragged item.
        If targetIndex > -1 Then
            ' Determine whether the mouse pointer is to the left or
            ' the right of the midpoint of the closest item and set
            ' the InsertionMark.AppearsAfterItem property accordingly.
            Dim itemBounds As Rectangle = ListView1.GetItemRect(targetIndex)
            If targetPoint.X > itemBounds.Left + (itemBounds.Width / 2) Then
                ListView1.InsertionMark.AppearsAfterItem = True
            Else
                ListView1.InsertionMark.AppearsAfterItem = False
            End If
        End If

        ' Set the location of the insertion mark. If the mouse is
        ' over the dragged item, the targetIndex value is -1 and
        ' the insertion mark disappears.
        ListView1.InsertionMark.Index = targetIndex

    End Sub

In the form load event i set ListView1.InsertionMark.Color = Color.Blue

That will allow the user to know if they will drop in front of or behind an item.

Should be all you need from what it sounds like.

I tried that code example of yours and managed to get a blue arrow on the dropped Listview, but unfortunately only when using SmallIcons View. And that was a vertical blue arrow. I need to use Details View, because I have 4 visible columns and over 90.000 rows in the ListView. So, thank's for the tip, it was a good one, but did'nt solve my problem yet. Any suggestions for using that InsertionMark property in Details View :)

Member Avatar for Unhnd_Exception

You can try this.

This should highlight the item the mouse is over while dragging.

Private LastItemOver As ListViewItem

    Private Sub ListView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragOver

        ' Retrieve the client coordinates of the mouse pointer.
        Dim TargetPoint As Point = ListView1.PointToClient(New Point(e.X, e.Y))
        Dim Item As ListViewItem = ListView1.GetItemAt(TargetPoint.X, TargetPoint.Y)


        If Item IsNot Nothing Then
            'set the current item over to highlighted.
            Item.BackColor = System.Drawing.SystemColors.Highlight
            Item.ForeColor = Color.White

            'if the last item over is not the current item
            'then reset its default colors
            If LastItemOver IsNot Nothing AndAlso Not LastItemOver.Equals(Item) Then
                LastItemOver.BackColor = Color.White
                LastItemOver.ForeColor = Color.Black
            End If

        ElseIf LastItemOver IsNot Nothing Then
            'there is no current item and there is a last item
            'reset the highlight
            LastItemOver.BackColor = Color.White
            LastItemOver.ForeColor = Color.Black
        End If

        'set the current item over to the 
        'last item over so it can be reset.
        LastItemOver = Item


    End Sub

    Private Sub ListView1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.DragLeave
        'reset the highlight if there is a current
        'highlighted item
        If LastItemOver IsNot Nothing Then
            LastItemOver.BackColor = Color.White
            LastItemOver.ForeColor = Color.Black
        End If
    End Sub

Well, I tried that, very easy solution and row under mouse was highlighted!!!
Didn't really think that myself, chancing the colors "manually" and not using some built-in event, which didn't work. I finally found out, that InsertionMark works in Details View with Vista, but not with XP (that I'm using). I'm really glad, that there is people like you, who will bother the solve other people's problems :)

You can try this.

This should highlight the item the mouse is over while dragging.

Private LastItemOver As ListViewItem

    Private Sub ListView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragOver

        ' Retrieve the client coordinates of the mouse pointer.
        Dim TargetPoint As Point = ListView1.PointToClient(New Point(e.X, e.Y))
        Dim Item As ListViewItem = ListView1.GetItemAt(TargetPoint.X, TargetPoint.Y)


        If Item IsNot Nothing Then
            'set the current item over to highlighted.
            Item.BackColor = System.Drawing.SystemColors.Highlight
            Item.ForeColor = Color.White

            'if the last item over is not the current item
            'then reset its default colors
            If LastItemOver IsNot Nothing AndAlso Not LastItemOver.Equals(Item) Then
                LastItemOver.BackColor = Color.White
                LastItemOver.ForeColor = Color.Black
            End If

        ElseIf LastItemOver IsNot Nothing Then
            'there is no current item and there is a last item
            'reset the highlight
            LastItemOver.BackColor = Color.White
            LastItemOver.ForeColor = Color.Black
        End If

        'set the current item over to the 
        'last item over so it can be reset.
        LastItemOver = Item


    End Sub

    Private Sub ListView1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.DragLeave
        'reset the highlight if there is a current
        'highlighted item
        If LastItemOver IsNot Nothing Then
            LastItemOver.BackColor = Color.White
            LastItemOver.ForeColor = Color.Black
        End If
    End Sub
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.