Problem with node flip


I have problem with adornments after node flipping (GoSilverlight, Silverlight 5).

I’ve found the Topic: Flipping (Mirroring) Nodes

and implemented similar code.

Attached project uses the next node (initial state):

Red and blue triangles are ports.

I’ve tried 2 cases of vertical (along Y-axis) flip:

1. Node is flipped.

Node selection is valid,

Port adornment is wrong:

2. NodePanel is flipped.

Port adornment is valid,

Node adornments are wrong after reselecting:

I’ve tried to call InvalidateMeasure() for parent FrameworkElements of Node/NodePanel, but result is the same.

Where is my mistake?

Here is code


using System;

using System.Windows;

using System.Windows.Controls;

using Northwoods.GoXam;

using System.Windows.Media;

namespace SLSchemaTest


public partial class MainPage : UserControl



public void FlipNode(Diagram dg, Node node, bool bFlipY, bool bFlipX) // bFlipY = true - flip along Y-axis; bFlipX = true - flip along X-axis


// DiagramPanel -> NodeLayer -> Node -> NodePanel -> STNode_Shape

NodePanel nodePanel = node.FindNamedDescendant("NodePanel") as NodePanel;

//FrameworkElement nodeShape = node.FindNamedDescendant("STNode_Shape") as FrameworkElement;

FrameworkElement elementToFlip = node; // Result: ports adornments bad, node adornments OK (after flip)

//FrameworkElement elementToFlip = nodePanel; // Result: node adornments bad, ports adornments OK (after flip)

FlipFrameworkElement(elementToFlip, bFlipY, bFlipX);

foreach (FrameworkElement port in node.Ports)

FlipPort(port, bFlipY, bFlipX);




private void FlipFrameworkElement(FrameworkElement el, bool bFlipY, bool bFlipX)


ScaleTransform scaleTransform = el.RenderTransform as ScaleTransform;

if (scaleTransform == null)


scaleTransform = new ScaleTransform();

scaleTransform.ScaleX = 1;

scaleTransform.ScaleY = 1;

el.RenderTransformOrigin = new Point(0.5, 0.5);


if (bFlipY)

scaleTransform.ScaleX *= -1; // vertical flip (along Y-axis)

if (bFlipX)

scaleTransform.ScaleY *= -1; // horizontal flip (along X-axis)

el.RenderTransform = scaleTransform;



private void FlipPort(FrameworkElement port, bool bFlipY, bool bFlipX)


Spot spot = SpotPanel.GetSpot(port);

if (bFlipY)

spot.X = (1 - spot.X);

if (bFlipX)

spot.Y = (1 - spot.Y);

SpotPanel.SetSpot(port, spot);

Spot linkSpot = Node.GetFromSpot(port);

if (bFlipY)

{// flip along Y-axis (vertical flip)

if (linkSpot == Spot.MiddleLeft)

linkSpot = Spot.MiddleRight;


if (linkSpot == Spot.MiddleRight)

linkSpot = Spot.MiddleLeft;


if (bFlipX)

{// flip along X-axis (horizontal flip)

if (linkSpot == Spot.MiddleBottom)

linkSpot = Spot.MiddleTop;


if (linkSpot == Spot.MiddleTop)

linkSpot = Spot.MiddleBottom;


Node.SetFromSpot(port, linkSpot);

Node.SetToSpot(port, linkSpot);

SpotPanel.SetAlignment(port, linkSpot);



internal void InvalidateParents(FrameworkElement elt)


if (elt != null)


FrameworkElement fe = elt;

while (fe != null)


//if (fe is DiagramPanel)

// break;


fe = VisualTreeHelper.GetParent(fe) as FrameworkElement;







[I answered the email, and forgot to post here.]

There's no need to do anything like InvalidateParents.

Here's a modified template that avoids the problems with the selection and resize handles:

<DataTemplate x:Key="TEST_NODE">
  <go:NodePanel Style="{StaticResource NodePanel_Style}" 
                Width="{Binding Path=Data.Width, Mode=TwoWay}" Height="{Binding Path=Data.Height, Mode=TwoWay}">
    <Viewbox x:Name="STNode_Flip">
      <Canvas Width="129" Height="65">
        <Path x:Name="Triangle" Width="129" Height="65" Margin="-0.49999, -0.500008, 0, 0" Stretch="Fill"
              StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF64FF00"
              Data="F1 M 128,64L 0.487796,63.55L 1.01035e-005,-7.62939e-006L 128,64 Z" />
        <local:STPort Width="27.8166" Height="14.755" Margin="-0.499998, -0.0851326, 0, 0" 
                      go:Node.PortId="Inlet" PortType = "IN" PortSide = "LEFT">
          <Path Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFF0000"
                Data="F1 M 26.8166,13.7231L 1.89269e-006,14.1699L 0.069669,0.414867L 26.8166,13.7231 Z" />
        <local:STPort Width="24.8295" Height="13.2551" Margin="103.195, 51.1372, 0, 0"
                      go:Node.PortId="Outlet" PortType = "OUT" PortSide = "BOTTOM">
          <Path Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF230FD2"
                Data="F1 M 127.524,63.8922L 103.695,63.5626L 104.029,51.6372L 127.524,63.8922 Z" />