private void treeviewDragVerifyHandler(object sender, DragVerifyEventArgs e) { // we need to go through all nodes that would be moved (source nodes), and check if there's any // problem moving any of them to the target node (circular references, etc.), since it's possible // for a element to exist multiple times in the treeview as different treenodes. List<ElementNode> nodes = new List<ElementNode>(e.SourceNodes.Select(x => x.Tag as ElementNode)); // now get a list of invalid children for this target node, and check all the remaining nodes against it. // If any of them fail, the entire operation should fail, as it would be an invalid move. // the target node will be the actual target node if it is directly on it, otherwise it would be the parent // of the target node if it would be dragged above/below the taget element (as it would be put alongside it). // also keep track of the 'permitted' nodes: this is used when dragging alongside another element: any children // of the new parent node are considered OK, as we might just be shuffling them around. Normally, this would // be A Bad Thing, since it would seem like we're adding a child to the group it's already in. (This is only // the case when moving; if copying, it should be disabled. That's checked later.) IEnumerable<ElementNode> invalidNodesForTarget = null; IEnumerable<ElementNode> permittedNodesForTarget = null; if (e.DragBetweenNodes == DragBetweenNodes.DragOnTargetNode || e.DragBetweenNodes == DragBetweenNodes.DragBelowTargetNode && e.TargetNode.IsExpanded) { invalidNodesForTarget = (e.TargetNode.Tag as ElementNode).InvalidChildren(); permittedNodesForTarget = new HashSet<ElementNode>(); } else { if (e.TargetNode.Parent == null) { invalidNodesForTarget = VixenSystem.Nodes.InvalidRootNodes; permittedNodesForTarget = VixenSystem.Nodes.GetRootNodes(); } else { invalidNodesForTarget = (e.TargetNode.Parent.Tag as ElementNode).InvalidChildren(); permittedNodesForTarget = (e.TargetNode.Parent.Tag as ElementNode).Children; } } if ((e.KeyState & 8) != 0) { // the CTRL key e.DragMode = DragDropEffects.Copy; permittedNodesForTarget = new HashSet<ElementNode>(); } else { e.DragMode = DragDropEffects.Move; } IEnumerable<ElementNode> invalidSourceNodes = invalidNodesForTarget.Intersect(nodes); if (invalidSourceNodes.Any()) { if (invalidSourceNodes.Intersect(permittedNodesForTarget).Count() == invalidSourceNodes.Count()) e.ValidDragTarget = true; else e.ValidDragTarget = false; } else { e.ValidDragTarget = true; } }
private void MultiSelectTreeviewElementsGroupsDragVerifyHandler(object sender, DragVerifyEventArgs e) { // we need to go through all nodes that would be moved (source nodes), and check if there's any // problem moving any of them to the target node (circular references, etc.), since it's possible // for a element to exist multiple times in the treeview as different treenodes. List <ElementNode> nodes = new List <ElementNode>(e.SourceNodes.Select(x => x.Tag as ElementNode)); // now get a list of invalid children for this target node, and check all the remaining nodes against it. // If any of them fail, the entire operation should fail, as it would be an invalid move. // the target node will be the actual target node if it is directly on it, otherwise it would be the parent // of the target node if it would be dragged above/below the taget element (as it would be put alongside it). // also keep track of the 'permitted' nodes: this is used when dragging alongside another element: any children // of the new parent node are considered OK, as we might just be shuffling them around. Normally, this would // be A Bad Thing, since it would seem like we're adding a child to the group it's already in. (This is only // the case when moving; if copying, it should be disabled. That's checked later.) IEnumerable <ElementNode> invalidNodesForTarget = null; IEnumerable <ElementNode> permittedNodesForTarget = null; if (e.DragBetweenNodes == DragBetweenNodes.DragOnTargetNode || e.DragBetweenNodes == DragBetweenNodes.DragBelowTargetNode && e.TargetNode.IsExpanded) { invalidNodesForTarget = (e.TargetNode.Tag as ElementNode).InvalidChildren(); permittedNodesForTarget = new HashSet <ElementNode>(); } else { if (e.TargetNode.Parent == null) { invalidNodesForTarget = VixenSystem.Nodes.InvalidRootNodes; permittedNodesForTarget = VixenSystem.Nodes.GetRootNodes(); } else { invalidNodesForTarget = (e.TargetNode.Parent.Tag as ElementNode).InvalidChildren(); permittedNodesForTarget = (e.TargetNode.Parent.Tag as ElementNode).Children; } } if ((e.KeyState & 8) != 0) // the CTRL key { e.DragMode = DragDropEffects.Copy; permittedNodesForTarget = new HashSet <ElementNode>(); } else { e.DragMode = DragDropEffects.Move; } IEnumerable <ElementNode> invalidSourceNodes = invalidNodesForTarget.Intersect(nodes); if (invalidSourceNodes.Count() > 0) { if (invalidSourceNodes.Intersect(permittedNodesForTarget).Count() == invalidSourceNodes.Count()) { e.ValidDragTarget = true; } else { e.ValidDragTarget = false; } } else { e.ValidDragTarget = true; } }