Custom link style puts moves the open connection to left top corner

In my project I have various templates for the links. But when I use a custom template for the open connection the open end of the connection always moves to left top corner. However for the default link it works fine.
I tried to replicate the same in demo and in Piping example I faced the similar problem,

Below are the changes made:

Subscribed to this event:

myDiagram.Model.Changed += ModelOnChanged;

    private void ModelOnChanged(object sender, ModelChangedEventArgs e)
    {
        if (e.Change.Equals(ModelChange.CommittedTransaction) && e?.OldValue != null)
        {

            var edits = (e?.OldValue as UndoManager.CompoundEdit).Edits.Select(edit => edit as ModelChangedEventArgs)
                .ToList();
            foreach (ModelChangedEventArgs lastOperation in edits)
            {
                switch (lastOperation?.Change)
                {
                    case ModelChange.AddedLink:
                        PipeData data = lastOperation.Data as PipeData;
                        Link link = myDiagram.PartManager.FindLinkForData(data, myDiagram.Model);
                        link.Route.RecomputePoints();
                        data.Category = "MyPipeTemplate";
                        break;
                }
            }
        }
    }

and I added the link template as below:

<go:DataTemplateDictionary x:Key="LinkTemplateDictionary">
            <DataTemplate x:Key="PipeTemplate">
                <go:LinkPanel go:Part.Reshapable="True"
                    go:Part.DropOntoBehavior="SplicesIntoLink">
                    <go:Link.Route>
                        <go:Route Routing="AvoidsNodes" Curve="JumpOver" Corner="5"
                    FromEndSegmentDirection="RotatedNodeOrthogonal"
                    ToEndSegmentDirection="RotatedNodeOrthogonal"
                    RelinkableFrom="True" RelinkableTo="True"
                    ToShortLength="5" />
                    </go:Link.Route>
                    <!-- in order to simulate a gradient across the breadth of the pipe, regardless of the pipe's direction,
             use multiple superimposed link shapes, each narrower and lighter than the previous one -->
                    <go:LinkShape 
              Stroke="{Binding Path=Link.IsDropOntoAccepted, Converter={StaticResource theStrokeChooser}}"
              StrokeThickness="5" />
                    <go:LinkShape Stroke="Gray" StrokeThickness="3" />
                    <go:LinkShape Stroke="WhiteSmoke" StrokeThickness="1" />
                    <Path go:LinkPanel.ToArrow="Triangle" Fill="Black" />
                </go:LinkPanel>
            </DataTemplate>

            <DataTemplate x:Key="MyPipeTemplate">
                <go:LinkPanel go:Part.Reshapable="True"
                      go:Part.DropOntoBehavior="SplicesIntoLink">
                    <go:Link.Route>
                        <go:Route Routing="AvoidsNodes" Curve="JumpOver" Corner="5"
                          FromEndSegmentDirection="RotatedNodeOrthogonal"
                          ToEndSegmentDirection="RotatedNodeOrthogonal"
                          RelinkableFrom="True" RelinkableTo="True"
                          ToShortLength="5" />
                    </go:Link.Route>
                    <!-- in order to simulate a gradient across the breadth of the pipe, regardless of the pipe's direction,
             use multiple superimposed link shapes, each narrower and lighter than the previous one -->
                    <go:LinkShape 
                Stroke="{Binding Path=Link.IsDropOntoAccepted, Converter={StaticResource theStrokeChooser}}"
                StrokeThickness="5" />
                    <go:LinkShape Stroke="Brown" StrokeThickness="3" />
                    <go:LinkShape Stroke="Blue" StrokeThickness="1" />
                    <Path go:LinkPanel.ToArrow="Triangle" Fill="Black" />
                </go:LinkPanel>
            </DataTemplate>
        </go:DataTemplateDictionary>

After these changes I could see the open connection is moving to the top left corner instead of staying at the place I dropped.

image(1)

Do you really need to recompute the route at the end of the transaction? What is wrong with the standard behavior?

We added the recomputePoints() as it was not updating the route values in our CustomLinkData earlier.

The problem with default behavior is that when I have customLinkTemplate and I try to create a openConnection with it. I expect that the open end of customLink stays where I dropped it. But in this case it goes to top left corner irrespective of where I drop it.

How is the link being added? Interactively or programmatically? And how?

Link is added interactively.

Also note that the default link works as expected but when its with custom link( with template mentioned above or any other template for that matter) I face this issue

Interactively how?

LinkIssue

We are setting the template for link in model changed event. Other than that we are not calling any diagram API’s.

If you comment out the ModelOnChanged listener, does the user’s drawing of a new link appear the way that you want?

Was your original problem that your model data wasn’t being updated with the new route? Wouldn’t it make more sense to update that property on the link data object directly, rather than recompute the route of the Link?

  1. Yes, if i comment out the ModelOnChanged listener, new link appear in the way i want, with default link template style. But the problem comes, when we set different link template. Also, we cannot set the template (link.Category) upfront, as there are some validations before connecting a link (if validation fails, we will make the connection as open connection with different template style).

  2. I tried by commenting the link.Route.RecomputePoints(); then also i face the same issue.

Other than the colors, your two link templates look the same to me. Is that the case?

What behaviors have you implemented when the user draws a new link?

To showcase the issue, we set the template simple. But our actual templates have different styles and we have around 10 templates.

When the user draws a new link, in IsConnectorValid() added some validation whether two nodes can be linked. On Valid using ModelChanged listener, will set the new template for the link.

Ah, and you are trying to have the new Link, created to replace the just drawn Link, have the same route?

The natural thing to do would be to change the Link’s category in a Diagram.LinkDrawn event listener. However, at that time I don’t think the new link’s route will have been determined yet.

So in your LinkDrawn listener you could call Route.UpdatePoints and then make a copy of the Route.Points. Add the link data object and the copied list of points to a collection in a global variable. Then you can change the link data’s category.

Then in your ModelOnChanged listener, when ModelChange.CommittedTransaction, run through the collection, calling PartManager.FindLinkForData to find the new Link corresponding to the link data (due to the new category) and set its Route.Points. Finally clear that collection so that you won’t set the route again.