Change link type/template depending on the spot the link starts from


I want to Change the type of link (and the temporary link template) that is being drawn/created depending on the originating spot.
I currently cannot find a way to achieve this, i.e. when the user starts dragging from the spot, know which spot this is and then set the link type and the temporary link template to use.

Any ideas?

Kind regards,

I think I already found a solution.

I can override the DoStart() method in the linking tool and use following code:

var port = this.FindLinkablePort();
var portId = port.GetValue(Node.PortIdProperty);

You probably don’t want to override LinkingTool.DoStart, since that might be too early in the process. More likely you’ll want to override LinkingTool.DoActivate, call the base method first, and then do what you want if this.StartPort != null.

Hello Walter,

thanks for your answer. Yes, if I use the DoActivate method I can directly Access the StartPort (instead of having to use FindLinkablePort() which also worked).

But now I’m having the Problem that changing the temporary link template doesn’t have the hoped for effect.
From inside the DoActivate I’m calling following code (see below).

Do I have to call some method so the change becomes active???


if (this.LinkType == LinkType.Timemonitoring)
	this.TemporaryLinkTemplate = this.LinkTemplatesDictionary["TemporaryTimemonitoringLink"];
	this.TemporaryLinkTemplate = this.LinkTemplatesDictionary.Default;

So you really want to use a different template for the temporary link? OK, I suppose it will work to override DoStart and setting the TemporaryLinkTemplate before calling the base method.

Alternatively you can just modify the TemporaryLink.

Yet more possibilities are available if you override CopyPortProperties and SetNoTargetPortProperties and modify the TemporaryLink as well as modifying a temporary port, as those methods normally do. At that time you can determine the temporary link’s appearance/behavior based on both ports, not just the starting port.

Hi Walter,

yes, I really want to have two different link templates for the temporary link. In my application, we have normal transitions that are drawn with a normal arrow and a timemonitoring Transition that is drawn with a dashed line and a stopwatch Image. According to the Transition the user creates the according template and also during drawing, the according temporary template should be used.

The first proposal doesn’t work. Just tried it out.

What exactly do you mean by modifying the TemporaryLink? What properties can I set there to make them use a specific template?

Your third proposal is beyond my current knowledge level. Have to dig into this to understand what you mean ;)

Currently, I’m trying another approach and want to get along with only one template and show/hide some of its content depending on the tag property of the temporary link object which I set in my linking tool. BUT this also doesn’t work. It seems my data binding might be wrong.

Perhaps you can have a look into this? I simplified the template a bit and currently only want to bind the TemporaryLink.Tag to a text block’s text (see below).

I tried following path expressions without success: “Tag”, “Data.Tag”, “Link.Tag”

Any ideas?

Thanks in advance,

<DataTemplate x:Key="TemporaryTimemonitoringLink">
	<go:LinkPanel go:Part.SelectionElementName="Path"
			<go:Route Routing="Normal"/>
		<go:LinkShape x:Name="Path"
					  Stroke="{x:Static SystemColors.HighlightBrush}"
					  StrokeDashArray="4.0 2.0"/>
		<Path Fill="{x:Static SystemColors.HighlightBrush}" go:LinkPanel.ToArrow="Standard" go:LinkPanel.Index="-1"/>
		<go:NodePanel Sizing="Auto" 
					  Background="{Binding RelativeSource={RelativeSource AncestorType=go:Diagram}, Path=Background}">
			<TextBlock Text="{Binding Path=Link.Tag}"/>

By “modifying TemporaryLink”, I meant to set properties on the UIElement/FrameworkElements of that Link.

I guess you are aware that there’s no traditional data binding for the temporary link. (There’s nothing to bind to!) Basically CreateTemporaryLink creates a new Link, sets Link.ContentTemplate, and returns it.

I don’t know about the bindings that you are trying. Certainly I would not expect Tag or Data.Tag to work. Are you setting Link.Tag, so that that binding could work?

I set the Tag value with both of These variants:

this.TemporaryLink.Tag = "blub";
this.TemporaryLink.SetValue(Link.TagProperty, "blub");

But with no success :frowning:

The LinkingTool does not set Link.Content, which is why there’s no data binding. But you could set it, and Bindings with a Path=Tag might work.

YES!!! :clap:

Setting the content and binding to its properties did the job!

Thank you very much!

I am actually trying to get the same thing to work but I have no idea what exactly to change and where to change it.
I tried overriding the DoActivate method in the LinkingTool and then set the templates but unlike changing the Template in the ClickCreatingTool, where I set the PrototypeData, which has its Category property set to the right DataTemplate, I can’t find anything similar here. TemporaryNodeTemplate and TemporaryLinkTemplate require a DataTemplate, which I have defined in my .xaml and I have no idea how to retreive it from within the LinkingTool. Setting TemporaryLink.Category throws an InvalidOperationException.

If you want to set TemporaryLinkTemplate, you need to override DoStart, not DoActivate. But I cannot tell what you really want/need to do.

The problem is that the LinkingTool is a general purpose tool but not all kinds of models have Links bound to their own data objects. In this case the LinkingTool cannot assume that the diagram is using a GraphLinksModel, which is the only situation where having a PrototypeData would make sense for creating a new link.

I am now grabbing the relevant DataTemplates from the xaml, storing them in the code and in my LinkingTool I’m setting TemporaryNodeTemplate, TemporaryLinkTemplate and TemporaryLink, which works as desired.