DraggingTool.IsValidLink not triggered

Hi,

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.

Can you help me?

Thx

That seems like a bug.

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.

Apparently this bug is already fixed in version 1.2 beta.

Where can I find the beta download?

I can confirm that the bug is indeed fixed in beta 1.2

Thanks for the confirmation.

Hi, I am new to GoXam and am interested in this type of senario. Can you share your source code here or outline the general approach? Thanks.

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.

You can grab this example in the GoXam for Silverlight samples. You can find them in the installation folder.