Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Drag and drop listviewitem on treenode

Status
Not open for further replies.

Black007

Programmer
Apr 6, 2005
29
BE
Need help regarding drag and drop between Listview and Treeview.

I've got the following situation :

On my form, I have a treeview on the left and a listview on the right.
The treeview holds the descriptive names of some article groups.
The listview is used to display the articles contained in an article group.

When i click a node on the Threeview, the listview gets filled with the
articles in that group. So far so good.

Here it comes :
I want to give the user to use some drag and drop functionality to change
the group to which an article belongs by using drag and drop.

So the user clicks 1 or more articles (multiple selections are allowed)
in the listview and he starts a drag. When the dragged items are dragged over
the Treeview, the respective nodes are highlighted but when the drop action
is instantiated, nothing happens. The group-id's of the articles in the
underlying database aren't changed.

I know the problem resides in the data structure created when instantiating
the drag and the datastructure that is returned when instantiating the drop
operation.

Is there a function available like Ctype to cast a listitem to a treenode.

Any help would be greatly appreciated.

 
There are obviously ways of restructuring the tree on the drop, but none that I am aware of are particularly easy.

Presumably the listviewitem has and itemid and a parentid.

The simple solution would be to change the parentid field of the dragged items to that of the id of the receiving node in the underlying database and then to clear and repopulate the tree.

Hope this helps
 
earthandfire,

That's exactly what I do behind the scenes.


Maybe I didn't describe the problem that well.
When id drag the Listviewitem over the Treeview, I always
get the Icon of "No Drop Allowed" instead of the neat drop-icon.

So mu track and trace works but the drag_enter won't work that well. Maybe I have to check for a special object in the e.getdata process ?
 
yes, allowdrop=true


this is the drag source

Private Sub LvwArtikels_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles LvwArtikels.ItemDrag
Dim myItem As ListViewItem
Dim myItems(sender.SelectedItems.Count - 1) As ListViewItem

Dim i As Integer = 0

' Loop though the SelectedItems collection for the source.
For Each myItem In sender.SelectedItems
' Add the ListViewItem to the array of ListViewItems.
myItems(i) = myItem
i += 1
Next
' Create a DataObject containing the array of ListViewItems.
sender.DoDragDrop(New DataObject("System.Windows.Forms.ListViewItem()", myItems), DragDropEffects.Move)

End Sub



This is the drop target
Maybe I have to change the getdatapresent and check for something else.

Private Sub TvwArtGroepen_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TvwArtGroepen.DragEnter

If e.Data.GetDataPresent("system.Windows.Forms.ListViewItem") Then
e.Effect = DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
End Sub

Private Sub TvwArtGroepen_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TvwArtGroepen.DragOver
'HITTEST
Dim Tv As TreeView = CType(sender, TreeView)
Dim Pt As Point = Tv.PointToClient(Tv.MousePosition)
Dim Tvi As TreeNode

Try
Tvi = Tv.GetNodeAt(Pt.X, Pt.Y)
Me.TvwArtGroepen.SelectedNode = Tvi
Catch s As Exception
End Try

End Sub

 
Sorry to be so long coming back to you, I had to go out.

I think the problem is as you say in GetDataPresent. It looks as if you are sending an array of listitems, but testing for a listitem.

Personally, in situations like this I tend to cheat.

Basically you need two pieces of information:
1: The list of items
2: The new parent

When the drag starts, store the list of items in a global array. Pass a *meaningless string to DoDragDrop. Check for that meaningless string in GetDataPresent. Get the node the mouse was released over, update your db and clear and repopulate the tree.

*when I say meaningless string, I mean something like %$^&*(, ie something that is unlikely to be genuine data. It also means that the drop will not take effect if GetDataPresent doesn't find that exact string.

Code:
If e.Data.GetDataPresent(DataFormats.Text) AndAlso e.Data.GetData("Text", True).ToString = "%$^&*(" ...

It may not be the most professional solution, but as long as you document it, its neat and simple.

Hope this helps. I've not tested it on a tree/list scenario, but I've used a couple of text boxes and it works as intended.

 
earthandfire,

Never mind the late response.

I'm pleased having someone trying to help me out.
I'll have a look into your solution. Seems neat indeed.

If it works out, I'll get back to you.

Thanks anyway

May the force be with you :)
 
Earthandfire,

Great cheat !
Works like a charm !

Thank you very much for the workaround tip !
 
The purists here wouldn't be impressed. [smile]

But, sometimes I think an 'alternative' solution is better than hours spent trying to get the 'ideal' solution. The most important thing with this sort of workaround, though, is to thoroughly document what you have done and why.

If you or someone else needs to work on this program at some stage in the future, they (or you) could waste a lot of time unnecessarily trying to work out was was going on.

I'm glad we got it sorted, though.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top