Creating a new LinkingTool


My application needs to have straight orthogonal links, but that do not connect to a fixed point. For example, if I select a ToSpot as TopSide, the first link will always connect in the middle of the top side. What I would want is the possibility to have a straight link without any corner if two nodes are (in this case) on top of each other (with some space between them for links, of course).

The only way I see of doing this is creating a new (Re)LinkingTool, which would perform such validation.

I’m not sure how to proceed. Should I override the FindLinkablePort() method to have it return a new Port? Or should I just implement this in the DoStop(), once a first link is created? Or something else I didn’t see?



How would the system know where you wanted that straight link to be? What if the nodes are of different widths, or are offset/skewed?

Oh, to answer the general implementation question: the LinkingTool can set the Link.Route.FromSpot and .ToSpot. That will cause the link to terminate at the spot you want.

You can override DoMouseUp, call the base method first, and then, if the TransactionResult is not null, look at the selected Link (Diagram.SelectedLink is a convenient way to get it).

As with all custom tools, install it by creating an instance of your tool and setting Diagram.LinkingTool.

(An alternative to defining your own LinkingTool is to define a Diagram.LinkDrawn event handler. But customizing the tool is more general.)

But you’ll still need to figure out where you want those link end points to be, which is what I was trying to get at in my previous reply.


Well, in my use case, the From nodes are always smaller than the To nodes, and connections can only be done from/to TopBottomSides.

Something like the following (sorry for the awful drawing…):

So basically, if the default Spot of a From node is within the Xmin to Xmax position of the To node, I’ll would use this “X” position.

I realize I have to translate an absolute Location to a relative position inside a Node. but that shouldn’t be too difficult.

Am I missing anything obvious?


No, that should work.

We should add some way to keep that effect when you move the From node(s) around relative to the big To node. Maybe in the release after this one.


You mention the following:

But as you mentionned in a later reply, there is no way of keeping that effect using a custom LinkingTool (not to mention that it also has to be done in a RelinkingTool).

So while I have it working as a LinkingTool, I still need to add a way of saving the new Spots so they could be used in a Save/Load diagram, and also handle the Node movement events.

If I understand correctly how it works, in an ideal world I would be using an event handler called after the Route.ComputePoints() method, but the Route class doesn’t have any valid Event. Using the Diagram.LinkDrawn doesn’t help either, since it’s raised by LinkingTool, which is not used when drawing links automatically (ie, model.Load).

The LayoutUpdated event generates too much noise to be useful.
I could use the LayoutCompleted event, to be sure it’s called once everytime the layout is updated, but I imagine it could be easily end up being recursive.

So what I now have in mind is getting bindings on Link.Route.ToSpot in order to be able to save/load these.

Would you have any thoughts/suggestions?



Persisting the Route.ToSpot is easy because Route.ToSpot is a dependency property, so you can do a TwoWay binding on it.

I think you could implement the Diagram.LayoutCompleted event handler that you suggest, where you update the Route.ToSpot appropriately for all of the Links. That might include setting Route.ToSpot = Spot.Default when you don’t want to specify a particular link point, for example when the nodes are too far apart horizontally for a straight vertical link.

If there is a Diagram.Layout with Conditions that include performing a layout after links are added or removed (and those are included in the Standard case), then you wouldn’t even need to implement a custom LinkingTool or RelinkingTool.