S
Stephan Steiner
Hi
Basically I'm trying to do something as in this CodeProject article:
http://www.codeproject.com/csharp/Explorer_Drag_Drop.asp
With the exeption that my Listview has to act like Windows Explorer
(within some boundaries.. in the end the goal is to have something
akin to your average FTP client with one window showing local and one
remote content).
I have pretty much all the explorer functionality down (copy/cut/paste/
delete/properties, navigation and whatnot). I can also drag and drop
files from my Listview to windows explorer (both copy and move), and
even dropping files dragged from Windows Explorer works - sort of. My
issue is with the ListView's InsertionMark - it remains set to the
first item visible in the ListView (so its index being 0) at all
times, so no matter where I let go of the mouse button, items are
dropped onto the first item currently visible in the ListView.
Here's a snippet of my code
private void fileBrowser_ItemDrag(object sender, ItemDragEventArgs e)
{
ListView lv = (ListView)sender;
string[] files = getSelectedFilesArray(lv);
if (files.Length > 0)
{
DoDragDrop(new DataObject(DataFormats.FileDrop,
files), DragDropEffects.Copy | DragDropEffects.Move);
}
}
This ought to be correct since dragging and dropping out of my app
works just fine.
And here's a working copy of the DragOver event handler:
private void fileBrowser_DragOver(object sender, DragEventArgs e)
{
// we need some filedrop data - otherwise indicate that
dropping won't work
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.None;
return;
}
if ((e.KeyState & SHIFT) == SHIFT && (e.AllowedEffect &
DragDropEffects.Move) == DragDropEffects.Move)
e.Effect = DragDropEffects.Move;
else if ((e.KeyState & CTRL) == CTRL && (e.AllowedEffect &
DragDropEffects.Copy) == DragDropEffects.Copy)
e.Effect = DragDropEffects.Copy;
else if ((e.AllowedEffect & DragDropEffects.Move) ==
DragDropEffects.Move) // default action = move
{
e.Effect = DragDropEffects.Move;
// here we could check if we're moving the file to
another drive and change to copy if so
}
else
e.Effect = DragDropEffects.None;
Point targetPoint = this.fileBrowser.PointToClient(new
Point(e.X, e.Y));
int targetIndex =
fileBrowser.InsertionMark.NearestIndex(targetPoint);
targetIndex = this.fileBrowser.InsertionMark.Index;
localFileSizeLabel.Text = "drop target : " + targetIndex +
" mouse X: " + e.X + " mouse Y: " + e.Y;
}
Since the InsertionMark is never changed from 0, targetIndex remains
-1 at all times (even though I see the mouse moving when I'm dumping
out the mouse position). And as my ListView is in detail mode,
ListView.FindNearestItem won't work to yield the item currently under
the mouse cursor.
Since I also need a proper InsertionMark for the DragDrop event (and
I'm not getting it), it explains why my files always end up in either
the currently visible directory, or if the first item is a folder, in
that folder.
How do I get the InsertionMark to cooperate?
Regards
Stephan
Basically I'm trying to do something as in this CodeProject article:
http://www.codeproject.com/csharp/Explorer_Drag_Drop.asp
With the exeption that my Listview has to act like Windows Explorer
(within some boundaries.. in the end the goal is to have something
akin to your average FTP client with one window showing local and one
remote content).
I have pretty much all the explorer functionality down (copy/cut/paste/
delete/properties, navigation and whatnot). I can also drag and drop
files from my Listview to windows explorer (both copy and move), and
even dropping files dragged from Windows Explorer works - sort of. My
issue is with the ListView's InsertionMark - it remains set to the
first item visible in the ListView (so its index being 0) at all
times, so no matter where I let go of the mouse button, items are
dropped onto the first item currently visible in the ListView.
Here's a snippet of my code
private void fileBrowser_ItemDrag(object sender, ItemDragEventArgs e)
{
ListView lv = (ListView)sender;
string[] files = getSelectedFilesArray(lv);
if (files.Length > 0)
{
DoDragDrop(new DataObject(DataFormats.FileDrop,
files), DragDropEffects.Copy | DragDropEffects.Move);
}
}
This ought to be correct since dragging and dropping out of my app
works just fine.
And here's a working copy of the DragOver event handler:
private void fileBrowser_DragOver(object sender, DragEventArgs e)
{
// we need some filedrop data - otherwise indicate that
dropping won't work
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.None;
return;
}
if ((e.KeyState & SHIFT) == SHIFT && (e.AllowedEffect &
DragDropEffects.Move) == DragDropEffects.Move)
e.Effect = DragDropEffects.Move;
else if ((e.KeyState & CTRL) == CTRL && (e.AllowedEffect &
DragDropEffects.Copy) == DragDropEffects.Copy)
e.Effect = DragDropEffects.Copy;
else if ((e.AllowedEffect & DragDropEffects.Move) ==
DragDropEffects.Move) // default action = move
{
e.Effect = DragDropEffects.Move;
// here we could check if we're moving the file to
another drive and change to copy if so
}
else
e.Effect = DragDropEffects.None;
Point targetPoint = this.fileBrowser.PointToClient(new
Point(e.X, e.Y));
int targetIndex =
fileBrowser.InsertionMark.NearestIndex(targetPoint);
targetIndex = this.fileBrowser.InsertionMark.Index;
localFileSizeLabel.Text = "drop target : " + targetIndex +
" mouse X: " + e.X + " mouse Y: " + e.Y;
}
Since the InsertionMark is never changed from 0, targetIndex remains
-1 at all times (even though I see the mouse moving when I'm dumping
out the mouse position). And as my ListView is in detail mode,
ListView.FindNearestItem won't work to yield the item currently under
the mouse cursor.
Since I also need a proper InsertionMark for the DragDrop event (and
I'm not getting it), it explains why my files always end up in either
the currently visible directory, or if the first item is a folder, in
that folder.
How do I get the InsertionMark to cooperate?
Regards
Stephan