Ports: dynamic IsValidFrom and To

I need a bit more control over the validity of linking certain nodes together. For example the following combinations are valid; any others are invalid…
Hub -> Router
Router -> Server
Server -> PC
PC -> Application
How do I achieve this? I’ve looked at sub-classing the GoPort class but I don’t know where to start! I’ve tried overriding the CanLinkFrom and CanLinkTo methods which look promissing but I don’t know where to get the From and To nodes from.
Thanks,
Ruaridh

You’re very close–you just needed to notice the “See Also … IsValidLink” in the help file entry for GoPort.CanLinkFrom.
We’ll add a sentence into the doc strings of CanLinkFrom and CanLinkTo to override GoPort.IsValidLink if you want to consider both ports in deciding validity.

Fantastic. Thanks very much.
Ruaridh

Ok I’ve created a sub-class of GoPort and overridden IsValidLink. All works great except that the links now look awfull compared to the standard GoPort. The links extend out from the center of each Icon, overwriting the icon and the nice bezier style links I had don’t look as nice as when I don’t fudge around with the port. I’m not sure if I’m plugging in my sub-class in the right place.
I have a sub-class of GoIconicNode where I override the CreatePort method to create my sub-classed GoPort. Is this the right approach? How do I maintain the default port and link appearance whilst still being able to override IsValidLink?
Thanks,
Ruaridh

You just need to set some properties on your new port. Here’s the definition of GoIconicNode.CreatePort:
protected virtual GoPort CreatePort() {
GoPort p = new GoPort();
p.Style = GoPortStyle.None;
p.Size = new SizeF(6, 6);
p.FromSpot = NoSpot;
p.ToSpot = NoSpot;
p.PortObject = this;
return p;
}

Excellent - much better now except that the links are still drawing in front of the GoIconicNodes whereas with the default port they are drawn extending from the edge of the nodes. Also the clickable “spot” (is that the right term?!) in the middle of the node is really, really small (only a couple of pixels high and a few across making it dificult to select with the mouse. Can I change the size and location of the spot?
I’m learning - soon I may even be able to help someone else!
Many thanks,
Ruaridh

  1. Are you sure you set the port’s PortObject to be either the Icon or the whole node? If you don’t set it, the natural end points for links will be the bounds of the port. If you set the PortObject to be the Icon, the links will end at the bounds of the Icon. If you set it to be the whole node, the links will end at the closest intersection point of all of the children.
    A poor-man’s way of doing this is by making sure the links are always drawn behind the nodes, by creating a new layer behind the one containing the nodes (and assigning it as the GoDocument.LinksLayer). However, this means arrowheads would not be drawn “correctly”.
  2. Just change the p.Size assignment in the CreatePort method.
    In the future we’ll provide the definitions of these Create… methods in the API documentation, so you won’t need to be puzzled about what they normally do.

Right first time - I set the PortObject to itself instead of the Icon Node. Works a charm now
Thanks,
Ruaridh