Listbox/Listview Drag & Drop

Reapz

Regular
Joined
Dec 15, 2002
Messages
74
I have a ListBox on a form in my App' which gets filled up at runtime with selections that the user makes. I would like the user to be able to move Items up and down the list by dragging and dropping but I have no clue where to start with this.

I found the help files confusing on this matter so if someone could point me in the right direction I'd appreciate it. Am I right in thinking that the first thing I need to do is change to a ListView instead of a ListBox.

Cheers!
 
Hi...
I prefer using the listview. First thing is to set the allow drop property to true, and in the events below, add:
C#:
private void listView1_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
{
                //start the drag drop process
	DoDragDrop(e.Item,DragDropEffects.Move );
}

private void listView1_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
{
	//only allow drop if it is another listviewitem
	if(e.Data.GetDataPresent(typeof(ListViewItem)))
	{
		e.Effect = DragDropEffects.Move; 
	}
}

private void listView1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
	//get the dropped and droppedon listview items - get the droppedon item from the mouse position
	ListViewItem droppedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));  
	PointF mouseLoc = listView1.PointToClient(new Point(e.X,e.Y));
	ListViewItem droppedOnItem = listView1.GetItemAt(Convert.ToInt16(mouseLoc.X) ,Convert.ToInt16(mouseLoc.Y) );
						
	if(droppedOnItem != null)
	{
		//inserts the droppeditem before the droppedon item and remove the original item
		listView1.Items.Insert(droppedOnItem.Index,droppedItem.Text,0);
		listView1.Items.Remove(droppedItem);  
	}
			
}
This is a straight forward implementation.. you will still need to do some work visually like highlighting the item that are being dragged over, etc.... but it should give you an idea.. :)

Cheers!
 
OK... I got it working... kinda. My App' is actually in VB.NET not C# but I fiddled about and managed to change it where needed. I got everything working perfectly I even added a bit so that you can drag an item to the end of the list but I hit a snag when playing about with the highlighting.

This is what I've got so far...

Visual Basic:
     Private Sub CurrentPlaylist_ItemDrag(ByVal sender As System.Object, ByVal e As ItemDragEventArgs) Handles CurrentPlaylist.ItemDrag
        DoDragDrop(e.Item, DragDropEffects.Move)
    End Sub

    Private Sub CurrentPlaylist_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles CurrentPlaylist.DragOver
        Dim Item As ListViewItem
        For Each Item In CurrentPlaylist.Items
            Item.BackColor = System.Drawing.SystemColors.Window
            Item.ForeColor = System.Drawing.SystemColors.WindowText
        Next

        If e.Data.GetDataPresent(GetType(ListViewItem)) = True Then
            e.Effect = DragDropEffects.Move
            Dim MouseLoc = CurrentPlaylist.PointToClient(New Point(e.X, e.Y))
            Dim HighlightItem As ListViewItem = CurrentPlaylist.GetItemAt(Convert.ToInt16(MouseLoc.X), Convert.ToInt16(MouseLoc.Y))
            If HighlightItem Is Nothing Then
            Else
                HighlightItem.BackColor = System.Drawing.SystemColors.Highlight
                HighlightItem.ForeColor = System.Drawing.SystemColors.Window
            End If
        End If

    End Sub

    Private Sub CurrentPlaylist_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles CurrentPlaylist.DragDrop
        Dim DroppedItem As ListViewItem = e.Data.GetData(GetType(ListViewItem))
        Dim MouseLoc = CurrentPlaylist.PointToClient(New Point(e.X, e.Y))
        Dim DroppedOnItem As ListViewItem = CurrentPlaylist.GetItemAt(Convert.ToInt16(MouseLoc.X), Convert.ToInt16(MouseLoc.Y))

        If DroppedOnItem Is Nothing Then
            CurrentPlaylist.Items.Remove(DroppedItem)
            CurrentPlaylist.Items.Add(DroppedItem)
        Else
            CurrentPlaylist.Items.Insert(DroppedOnItem.Index, DroppedItem.Text)
            CurrentPlaylist.Items.Remove(DroppedItem)
        End If

        Dim Item As ListViewItem
        For Each Item In CurrentPlaylist.Items
            Item.BackColor = System.Drawing.SystemColors.Window
            Item.ForeColor = System.Drawing.SystemColors.WindowText
        Next
    End Sub

Like i said this works but when the mouse button is held down the ListView flickers and that just looks crap. Obviously I'm doing it wrong but can't think of a better way.

Also I would like to change the mouse cursor to the text of the item being dragged, like in windows explorer, but I don't know if that' possible.
 
Back
Top