Reputation: 1406
The 1.66 (March 2022) release introduces a TreeDragAndDropController API which allows for handling drag & drop events for custom tree views.
However in the docs for the DataTransfer object is says:
Drag and drop controllers that implement {@link TreeDragAndDropController.handleDrag
handleDrag
} can add additional mime types to the data transfer. These additional mime types will only be included in thehandleDrop
when the the drag was initiated from an element in the same drag and drop controller.
Does this mean that you cannot drag & drop between custom tree views as they would typically have a custom drag & drop controller per view? Or that you're meant to re-use a drag & drop controller between tree views in order to enable dragging & dropping between views?
I have tried various combinations and been unsuccessful in getting a full drag & drop between two tree views. I do see an error in the console on drop in some situations but that is about it.
Upvotes: 1
Views: 1045
Reputation: 41
It took me a while to figure out how to get drag & drop to work between two different treeviews. For me, the problem was a combination of:
dragMimeTypes
.treeDataTransfer.set()
.This is probably best described by way of example. Let's assume we're only going to drag from TreeView_A and we'll only drop onto TreeView_B.
For TreeView_A
dropMimeTypes
can be an empty array as we're not expecting to receive any drops.dragMimeTypes
needs to include the mime type of the treeview that we're going to drop onto (i.e. TreeView_B). A word of warning here, this MUST be in the format application/vnd.code.tree.<treeidlowercase>
. So, for this example it would read something like this:dragMimeTypes = ['application/vnd.code.tree.treeView_b'];
handleDrag()
method needs to set using a mime type of the target treeview (Treeview_B), (remember lowercase!) public async handleDrag(source: TreeItem[], treeDataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<void> {
treeDataTransfer.set('application/vnd.code.tree.treeView_b', new vscode.DataTransferItem(source));
}
The lowercase requirement seems more like a suggestion if you read the comments in the underlying code... but no from my experience it seems more like a requirement. Had me stumped for ages!
For TreeView_B
dragMimeTypes
can be an empty array as we won't be dragging anything from here.handleDrag()
method.dropMimeTypes
needs to include the mime type of the treeview that we're going to drop onto (i.e. this treeview, TreeView_B)dropMimeTypes = ['application/vnd.code.tree.treeView_b'];
handleDrop()
method needs to get the correct mime type (you guessed it, Treeview_B in lowercase). In this method, I just log to console. public async handleDrop(target: TreeItem | undefined, sources: vscode.DataTransfer): Promise<void> {
const transferItemAppContent = sources.get('application/vnd.code.tree.treeView_b');
if (transferItemAppContent) {
console.log(JSON.stringify(transferItemAppContent));
return;
}
}
I'm still not sure that I've 100% understood how this is supposed to be implemented, but I can tell you that the above method works. Hope it helps.
Upvotes: 3