views:

517

answers:

1

1) How do you move items in a ListView using Drag&Drop? I have implemented D&D copy for files dragged from a directory.

2) BTW, how do you get a directory link by D&D to ListView, I've seen applications that get the directory path by D&D from address bar of Windows Explorer.

private void lvwFiles_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}

private void lvwFiles_DragDrop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        var paths = (string[])e.Data.GetData(DataFormats.FileDrop);
        var path = Path.GetDirectoryName(paths[0]);
        paths = Media.FilterPaths(paths);
        lvwFilesAdd(path, paths);
        lvwFilesWrite();
    }
}

Found this @ Microsoft (VS2005; http://support.microsoft.com/kb/822483), I'm trying to make sense of this code and make it work in my program. I'll see how to separate this from the code already in the DragEnter & DragDrop event handlers.

//lvwFiles_ItemDrag event handler
//
//Begins a drag-and-drop operation in the ListView control.
lvwFiles.DoDragDrop(lvwFiles.SelectedItems, DragDropEffects.Move);

//lvwFiles_DragEnter event handler
//
int len=e.Data.GetFormats().Length-1 ;
int i;
for (i = 0 ; i<=len ;i++)
{
    if (e.Data.GetFormats()[i].Equals("System.Windows.Forms.ListView+SelectedListViewItemCollection"))
    {
        //The data from the drag source is moved to the target. 
        e.Effect = DragDropEffects.Move;
    }
}

//lvwFiles_DragDrop event handler
//
//Return if the items are not selected in the ListView control.
if(lvwFiles.SelectedItems.Count==0)
{
   return;
}
//Returns the location of the mouse pointer in the ListView control.
Point cp = lvwFiles.PointToClient(new Point(e.X, e.Y));
//Obtain the item that is located at the specified location of the mouse pointer.
ListViewItem dragToItem = lvwFiles.GetItemAt(cp.X, cp.Y);
if(dragToItem==null)
{
    return;
} 
//Obtain the index of the item at the mouse pointer.
int dragIndex = dragToItem.Index;
ListViewItem[] sel=new ListViewItem [lvwFiles.SelectedItems.Count];
for(int i=0; i<=lvwFiles.SelectedItems.Count-1;i++)
{
    sel[i]=lvwFiles.SelectedItems[i];
}
for(int i=0; i<sel.GetLength(0);i++)
{ 
    //Obtain the ListViewItem to be dragged to the target location.
    ListViewItem dragItem = sel[i];
    int itemIndex = dragIndex;
    if(itemIndex==dragItem.Index)
    {
        return;
    }
    if(dragItem.Index<itemIndex)
        itemIndex++;
    else
        itemIndex=dragIndex+i;
   //Insert the item at the mouse pointer.
   ListViewItem insertItem = (ListViewItem)dragItem.Clone();
   lvwFiles.Items.Insert(itemIndex, insertItem);
   //Removes the item from the initial location while 
   //the item is moved to the new location.
   lvwFiles.Items.Remove(dragItem);
}
+2  A: 

Have a look at ObjectListView -- an open source wrapper around a .NET WinForms ListView.

It supports rearranging list view items by dragging, plus a whole lot more. See Taking the drag out of Drag and Drop

alt text

Grammarian
Thanks for the link. The source has over 20 .cs files and one of them has over 9,000 lines, I only wanted to know how to do it having in mind that I'm already using the event for something else like D
OIO
It does do a lot, you're right. Doing dragging within a list is quite different from accepting drops from other applications. It's actually quite complicated once you take auto scrolling and UI feedback into account. ObjectListView does a lot of work to make it easy for other programmers to use it.
Grammarian