Drag and Drop

Hi Walter,

I’m using the WPF version, and I’ve figured out how to use the drag-and-drop (I use telerik tree-view as the source, very similar to this post).

I need to custom this simple behaviour like this:

1. Allow multi selection dragging.

2. Send a class/collection in the drag event args that is not the type that the GraphLinksModel knows.



I guess i’ll need to override some behaviours, but is that possible?

Sorry, but I’m not familiar with any of the Telerik controls. So I don’t know how (or if?) they represent collections of (selected?) items.

The post you referred to shows how it’s done with the Silverlight toolkit; it was copied and adapted from the WPF drag-and-drop implementation.

Because drag-and-drop is built-into WPF, you can override the DraggingTool.DoDrag…, DoDrop, DoGiveFeedback, DoQueryContinueDrag, and the MayCopyExternal and MayMoveExternal methods.

Don’t worry about the control is by Telerik, my problem is more general:

1. I have a collection of items to be dragged.

2. The items cannot be in the same type of my diagram model type (because items from the tree can be dragged to a different control).



How can I achieve that while keeping the nice looking dragged item being created as the item is being dragged on the diagram?

Can I avoid overriding all the drag methods you’ve mentioned (DraggingTool.DoDrag…, DoDrop, DoGiveFeedback, DoQueryContinueDrag, and the MayCopyExternal and MayMoveExternal)?



Is there a sample for that kind of overriding?



Thanks

Well, one possibility is to change the call to DragDrop.DoDragDrop in your tree control so that the DataObject includes not only the data that it currently uses but also the data that your Diagram.Model uses, with the data format being the type of your node data.

Thanks! I ended up with a bit different solution: the tree control sends its own data object, and in the DraggingTool I'm overriding the DoDragEnter and adds the diagram object type to the DataObject.
public override void DoDragEnter(DragEventArgs e) {
TreeItem droppedItem = e.Data.GetData(typeof(TreeItem)) as TreeItem;
//Prepare the object to be dropped
if(droppedItem != null) {
MyDiagramItem diagramItem = new MyDiagramItem(droppedItem));
e.Data.SetData(diagramItem);
}
base.DoDragEnter(e);
}

I still don’t know how to make the diagram drag-and-drop multiple items:
If I set on the DataObject a number of items, it treats only the first one. What is the best way to handle multiple drag/drop?

Instead of the data being an instance of MyDiagramItem, have it be a DataCollection of MyDiagramItems.

The DataCollection class is a nested class of the …Model class that you are using.

I’m using the DataCollection, but I probably doing something wrong (couldn’t find any example) because now the diagram doesn’t recognize the dropped data at all. This is my code:



public override void DoDragEnter(DragEventArgs e)

{

IEnumerable droppedItems = e.Data.GetData(typeof(TreeItem[])) as IEnumerable;



MyDiagramModel.DataCollection dataCollection = new MyDiagramModel.DataCollection();



if (droppedItems != null)

{

foreach (TreeItem droppedItem in droppedItems)

{

//Prepare the object to be dropped

MyDiagramItem diagramItem = new MyDiagramItem(droppedItem));

dataCollection.AddNode(canvasUnit);

}

e.Data.SetData(dataCollection);

}

base.DoDragEnter(e);

}

That looks OK to me.

Try setting the data format explicitly:
e.Data.SetData(this.Diagram.Model.DataFormat, dataCollection);

Sorry for the hassle, but still no go…

It seems to have some effect - while dragging item(s) the Copy drag effect shows up for a split of a second every once in a while, but other then that - nothing. Any idea?

Try setting dataCollection.Model to your model.

Or try calling …Model.CreateDataCollection() instead, which does this initialization for you.

When I get a chance I can investigate this more carefully.

hallelujah!

Model.CreateDataCollection() works.



Thank you very much.