I have a situation where I have 2 XamDataTrees that I need to be able to drag and drop items from one to the other.
Data structure consists of Schemas, Groups, Nodes, Leaves:
What we want to achieve with dragging:
Since the tree is particular about the type when dragging and dropping, this is proving to be a challenging problem. Deriving from a base type gets things working, but I can't disallow things like dragging a node from Tree 2 into a schema in Tree 1. This seems to be a problem of the IsDropTarget being conditional on what the drag source type is and I can't figure out how to make that happen with this control. Any help would be appreciated.
I have been investigating into your requirement, and at the moment, none of the drag-drop related events that the XamDataTree exposes will really let you restrict drag and drop from one node to another, especially if they are all derived from a base type and the collections that make up your layout are child collections of that base type as you have mentioned.
With that said, some time ago I did derive a solution for another forum thread discussion using the IsEnabledMemberPath of the NodeLayout and the NodeDraggingStart and NodeDragEnd events so that you can disable certain underlying data items from being dragged to depending on the type that you are currently dragging. That forum thread, along with a sample project I wrote for it is located here: https://www.infragistics.com/community/forums/f/retired-products-and-controls/105253/xamdatatree-drag-drop-within-the-parent-node. Please disregard the mentioning of the “Silverlight” XamDataTree, as the XamDataTree was a shared control between Silverlight and WPF, back when we still supported Silverlight.
By setting the underlying property that the IsEnabledMemberPath is pointed at such that some nodes will be disabled, your end user will not be able to drag to the nodes that are disabled. The same can be said from Tree 1 to Tree 2 in this case if you mark the IsEnabledMemberPath for all of the items in Tree 2 to be disabled when a node begins dragging in Tree 1. Then, you can reset the underlying IsEnabledMemberPath property in the NodeDragEnd event.
I hope this helps you. Please let me know if you have any other questions or concerns on this matter.
Thanks for the reply.
The thread that you pointed me to isn't terribly helpful because the NodeDraggingStart event doesn't appear to know at any point what the droptarget will be. What I really need is the ability to disable the droptarget dependent on the types for both the dragsource and the droptarget.
With that said, I was able to get something kind of working through the NodeDragDrop event. I look for the type on both the dragnode and the droptarget, then set
e.DragDropEventArgs.OperationType = Infragistics.DragDrop.OperationType.DropNotAllowed;
e.Handled = true;
This seems to work, the only issue at this point is the styling of the cursor as it hovers over the droptarget. It indicates that a drop should be possible, but this logic disables it. Any clues on how I can restyle the template?
I am unsure that the NodeDragDrop event will really help you here, as this event does not fire until you actually “drop” the node being dragged. So, while you are setting something that would disallow the drag drop operation, this will only happen once the user tries to drop the node.
I will continue to make the recommendation for the IsEnabledMemberPath in this case, and I am attaching a simple sample project that demonstrates how you can do this. In the sample, you will be able to drag within the same XamDataTree, but dragging to the “other” tree will only allow you to drag onto an “even” or “odd” indexed node due to some operations in the NodeDraggingStart event that set the property on the underlying data item that is mapped to the IsEnabledMemberPath. This will disable the nodes that you cannot drag to while the drag is in progress, and in the NodeDragEnd, the nodes are re-enabled. The disabled nodes will automatically change their drag template when you drag over them because, since they are disabled, you cannot drop on them. In the case of your application, rather than doing this with even and odd, I would recommend that you do this with your types, making logic checks for whether you are dragging a Schema, Group, Node or Leaf, and disabling other nodes based on what is being dragged.
Thanks for the reply!
Unfortunately it doesn't seem to work when using hierarchical data. I can disable the schemas at the top and that appears to work, but it still allows a drop into the collection of the schema's children. And because I don't have any idea for how that structure will look or how deep it will go, I have to do it recursively.
I did find a way to do something similar in the DraggingStart event by setting the IsDropTarget property on the XamDataTreeNode. Again I have to go through the XamDataTreeNodesCollection recursively looking for the types, but doing it that way by setting IsDropTarget to false appears to work. Any thoughts on that approach?
It is true that if you disable the parent “schema” node, but the child nodes are still enabled that since they are deriving from the same base class, it will still be possible to drag to them.
Regarding a recursive method to loop through all nodes in the XamDataTree though, I would recommend something like the following:
public void RecursiveNodeCheckMethod(Type type, XamDataTreeNode parent)
if(parent.Data.GetType() == type)
// Type matches
// Type does not match
foreach(XamDataTreeNode node in parent.Nodes)
If you call into this using a simple loop through the top-level Nodes collection of the XamDataTree and call into it for each node, this will allow you to check all of the nodes and pass in the exact Type that you are looking for. The “parent.Data” above will return the underlying data item of each node, so you can check that against each node being looped through.
I hope this helps. Please let me know if you have any other questions or concerns on this matter.