views:

1232

answers:

4

Using WPF I've succeeded at implementing drag and drop to rearrange items within a list(view or box) and also to drag and drop items between lists.

Now I am trying figure out how to implement drag and drop with NESTED lists.

For instance I have a listview containing projects and each project item contains another listview of tasks. I want to be able to drag and drop to rearrange the order of projects and also to reorder tasks and move them between projects.

I have code that successfully does one of the other, but I can't figure out how to do both.

It seems like there is some sort of painful solution that would involve hit testing and maybe the z-order of the nested lists, but I can't find any examples of this.

Can anybody offer any pointers?

FYI: The working code that I currently have implemented is based on the following two excellent articles on WPF drag and drop:

http://bea.stollnitz.com/blog/?p=53 http://www.codeproject.com/KB/WPF/ListViewDragDropManager.aspx

+2  A: 

Just first thoughts is, why not use a TreeView instead of a ListView if you're going to have nesting?

Davy8
Good thought... I think that would make it simpler to implement the drag and drop functionality... but it would give me some new UI look and feel challenges...
Scrappydog
A: 

AllowDrop must be true on any control.

+1  A: 

Since MouseMove and most others in wpf are routed events, you could just check e.OriginalSource in a common event handler. Then you can decide which element to drag based on which element the mouse was on, probably using one of those "find parent which satisfies condition" helper method techniques. Additionally, you can set e.Handled if you have several elements in the visual tree subscribing to the event.

kek444
A: 

I went through a similar issue when working on an app with listboxes of nested user controls.
I handled all of this in the PreviewMouseButtonDown event on a per control level. I check the coordinates of the point that was clicked. If it came from anywhere in the parent ListBoxItem that was not in the ListBox, I process the the DragDrop.DoDragDrop() there. If it came from inside the ListBoxItem, I let it bubble down to the child ListBox's PreviewMouseButtonDown event. I check to see where the location is in the child ListBox to see which item was clicked on so I can grab it and do the DragDrop on this level instead. The pseudo-code is as follow:
Parent ListBox
-- PListBoxItem1
-- PListBoxItem2
-- PListBoxItem3
---- Child ListBox
------ Child ListBoxItem1
------ Child ListBoxItem2 -Click drag started here
------ Child ListBoxItem3

Parent_List_Box_PreviewMouseButtonDown
If mouse position is not inside the Child ListBox Then
DoDragDrop() on the Parent level with this ListBoxItem
End If

Child_ListBox_PreviewMouseButtonDown
Determine which item the mouse was clicked on relative to the Child ListBox
DoDragDrop() on the Child level with this ListBoxItem

So since the click was inside a Child's ListBox, the event bubbles down to the lowest handler that passes the criteria for the DragEvent.

Hope this helps!

Stephen McCusker