Override FindLinkablePort

Hello,

I have a lower layer, on which the user is supposed to draw the diagram. If necessary the user can blend in another layer above it. This top layer is half transparent and should not be interactible, like a template the user can recreate on the lower layer. Now, while the nodes on the top layer are not interactible and the nodes dragged from the palette are indeed dropped on the lower layer, I can still pick up the ports and draw links from the top layer, while I cannot do so on the bottom layer. In the latter case the nodes simply get moved around.
In order to make this work I wanted to override the FindLikablePort in the diagram function but I’m unsure how this function is supposed to find the actual Port and what happens when the lower node is overshadowed by an upper node. How would I do it and is this the right approach?

What happens when you set Layer.AllowLink to false on that top layer?

As I have already overridden IsValidFrom in the LinkingTool before, I’ve simply extended the query for valid starting points to not match for nodes on the top layer.

The more difficult problem is to enable linking for nodes on the lower layer. I found out it does work if the node is not overshadowed by another node on the top layer, but otherwise it does not. I assumed overriding FindPartAt would suffice but the function is not being called at all.

LinkingTool.CanStart calls this method, which you can override to skips certain layers:

    protected virtual FrameworkElement FindLinkablePort() {
      Diagram diagram = this.Diagram;
      if (diagram == null) return null;
      FrameworkElement elt = this.StartElement;
      if (elt == null) elt = diagram.Panel.FindElementAt<FrameworkElement>(diagram.FirstMousePointInModel,
                                 Diagram.FindAncestorOrSelf<FrameworkElement>, x => true, SearchLayers.All);
      Node node = Diagram.FindAncestor<Node>(elt);
      if (node == null) return null;
      // don't search for valid ports "underneath" the object at the current mouse point;
      // only search up the parent tree of elements for one that IsValidFrom
      FrameworkElement port;
      LinkingDirection dir = this.Direction;
      if (dir == LinkingDirection.Either || dir == LinkingDirection.ForwardsOnly) {
        port = FindElementUpFrom(elt, Node.GetLinkableFrom, x => IsValidFrom(node, x));
        if (port != null) {
          this.Forwards = true;
          return port;
        }
      }
      if (dir == LinkingDirection.Either || dir == LinkingDirection.BackwardsOnly) {
        port = FindElementUpFrom(elt, Node.GetLinkableTo, x => IsValidTo(node, x));
        if (port != null) {
          this.Forwards = false;
          return port;
        }
      }
      return null;
    }