Implement Copy Drag
The purpose of this tutorial is to show you how to implement "Copy Drag".
Copy Item When Dragging from One TreeView to Another
Using the new DragDrop mode, you can control the DropAction of a drop operation. You can do so through the TreeViewDragDropOptions object as described in the DragDrop tutorial.
In this section you will see how to implement copy drag, when dragging items from one data-bound treeview to another. On the next figure you can see the initial staging.
There are two treeviews populated with some hierarchical data. On the left side is the source treeview (the one from which the items will be copied). On the right side is the target treeview (the one in which the items will be dropped).
Both RadTreeViews are data bound to a collection of business objects. For more information, read the Binding to Object topic.
Here is the initial XAML:
In the current situation if you try to drag and drop from the left treeview to the right, the items will be moved (not copied). The same is valid if you try to drag and drop from the right treeview to the left. And in order to change that logic and implement a copy drag operation from the left to the right RadTreeView you need to:
-
Attach a DragDropManager DragOver event handler for the right RadTreeView:
RadTreeView handles internally the DragDropManager events and in order to invoke a custom handler, you need to explicitly specify that you're adding a handler that should be invoked even for already handled events. This is done through the last - bool argument of the DragDropManager.AddDragOverHandler extension method.
-
In the event handler you should use the following code:
Here is the final result:
Now if you try to drag an item from the right RadTreeView and drop it in the left tree, the item will be moved. This is due to the fact that we changed the DropAction only while dragging over items of the right RadTreeView. If you need to implement a copy operation when dropping into the left RadTreeView, you'll have to attach an event handler for its DragDropManager DragOver event as well:
If you try to implement the above approach on two declaratively defined RadTreeView controls, you'll encounter an exception. This is due to the fact that the copy operation will try to add one object instance in two different RadTreeView controls. And if you're working with visual objects, then this would raise an exception as you can't use the same visual object multiple times in the VisualTree of the application. Therefore in this case, you'll have to implement a custom copy operation that creates a new object copying the settings of the dragged RadTreeViewItem.
Copy Item When Dragging Within the Same TreeView
In this section you will see how to implement copy drag, when dragging items within the same RadTreeView. On the next figure you can see the initial staging.
Here is a treeview populated with some hierarchical data. This is the initial XAML declaration:
The RadTreeView is data bound to a collection of business objects. For more information, read the Binding to Object topic.
Before setting a copy DropAction within one RadTreeView, you need to consider the fact that in the RadTreeView once you add the same instance of an object, all item manipulation operations will be applied on every instance of the object found within the RadTreeView control. This basically means that if you follow the approach described in the previous section of the article, you will get multiple RadTreeViewItems wrapping the same object instance. Once you do so, you'll have to work with all items as one as the RadTreeView can't differentiate them. If this is something you;d like to avoid, then you'll have to reconfigure the default RadTreeView drag/drop operation to make a real copy of the dragged item and drop the copy.
In order to implement a real copy drag operation, you need to perform the following steps:
-
Attach DragDropManager Drop and DragDropCompleted handlers on the RadTreeView:
RadTreeView handles internally the DragDropManager events and in order to invoke a custom handler, you need to explicitly specify that you're adding a handler that should be invoked even for already handled events. This is done through the last - bool argument of the DragDropManager.AddDragOverHandler extension method.
-
In the OnDrop event handler you should stop the drop operation. You can do so by setting the DropAction to None:
-
In the OnDragDropCompleted event handler you should implement a custom drop operation. However, as this drop operation will have to create a real copy of the dragged item, you will need to create methods to copy your objects. For example, here are sample methods which copy respectively the Team, the Division and the League objects:
-
Next, you need to implement a custom drop operation in the OnDragDropCompleted event handler. This means that you need to define a logic that tracks the type of the dragged item as well as the type of the drop destination to make sure that the drop is actually allowed. This logic will also have to track the DropPosition to decide where to insert the real copy of the dragged item.
With this the real copy DragDrop implementation is ready. The final result can be seen on the next snapshots.
Copy Team:
Copy Division:
Copy League:
You can further customize this solution by applying a logic that determines the DropAction based on the type of the item the drag operation is currently over: