I’ve encountered a problem that I can’t seem to figure out.
I have a TreeModel diagram with the DropOntoEnable=true that when I drag a specific node into another node, the background of the drop onto node turns into red.
But if the drop onto node is by any chance selected, then the background doesn’t changes to red.
I’ve extended from the DraggingTool class and overrided the IsValidLink to return always true. In the first case when I drag the node (but didn’t release it) the IsValidLink is called. But in the last case the IsValidLink isn’t called when the node is dragged. It is only called when I release it.
Try using the following override of DraggingTool.ConsiderDragOver:
[code] public class CustomDraggingTool : Northwoods.GoXam.Tool.DraggingTool {
public CustomDraggingTool() {
this.DropOntoEnabled = true;
}
// this is a simplified definition of the standard ConsiderDragOver
protected override bool ConsiderDragOver(Point pt, Part p) {
if (p == null) return false;
DropOntoBehavior action = p.DropOntoBehavior;
if ((action & DropOntoBehavior.AddsLinkFromNode) == 0) return false;
Dictionary<Part, Info> parts = this.CopiedParts ?? this.DraggedParts;
if (parts == null) return false;
if (parts.ContainsKey(p)) return false;
if (p is Adornment) return false; // not likely to be an Adornment, since we're not searching Temporary layers
Node nd = p as Node; // dropped-onto part must be a Node
if (nd == null) return false;
if (!parts.Keys.OfType<Node>().Any(n => LinkableFromStationaryNode(n, parts, nd))) return false;
return true;
}
private bool LinkableFromStationaryNode(Node n, Dictionary<Part, Info> dragged, Node stationary) {
if (n == null) return false;
if (n == stationary) return false; // shouldn't happen, but might as well check anyway
var links = n.LinksInto.ToList();
if (links.Count > 1) return false; //?? multiple links: disallow
Link relink = null;
if (links.Count == 1) { // one link: relink if not connected with a dragged node
relink = links.First();
Node other = relink.FromNode; // assume IsValidLink will check for relink valid
if (other != null && dragged.ContainsKey(other)) return false;
} // zero links: new link, only need to check IsValidLink
// ignore all nodes that are members of a dragged Group
if (dragged.OfType<Group>().Any(g => n.IsContainedBy(g))) return false;
return IsValidLink(stationary, n, relink);
}
}[/code]
I would caution you though, not to override IsValidLink to always return true. In this situation it’s supposed to be checking to maintain a tree structure.
You can customize link validation either in the model or in the diagram.
In the diagram, the IsValidLink method can be overridden on DraggingTool or LinkingTool and RelinkingTool to decide whatever you want. I would recommend returning false if the base method returns false, so that you get all of the standard behaviors.
The default implementations of link validation in the tools just call the IsLinkValid or IsRelinkValid methods of the model. If you want to customize the model’s validation, just override the CheckLinkValid method.
There isn’t a sample that customizes the link validation for the DraggingTool, but the FlowChart sample does customize the LinkingTool and the RelinkingTool.