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?
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.
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.
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.