Node of 0x0px visual glitch

Hi Walter, here is the the situation. I have 2 nodes of 0x0px linked by a Link. When I perform some action, I add new link from both side of the existing link and add a node at the extrimity of these 2 links. Why there is a little space between my links? And you know what is weird, when I close the form and reopens it, the space disapear.

My first reaction is that perhaps SnapsToDevicePixels=“True” or UseLayoutRounding=“True”. Note that these properties could have been inherited.

The effects are also dependent on the precise DiagramPanel.Position and Scale, i.e. scroll and zoom, which might account for the different appearance when re-opening the diagram.

I tried to apply SnapsToDevicePixels and UseLayoutRounding on the Diagram, but nothing changed. And I looked at the Scale and Position, and they don’t changed when I reopen the form. No other ideas?

So you tried setting them to “False”, yes? I was guessing that the rounding was the cause.

Maybe there’s something odd about handing zero-sized objects.
Try setting them to be 0.01x0.01 width & height.

Yes I set them to False, but it didn’t work.

I tried to fix the size to 0.01, and no changed… Maybe if I show you my DataTemplate it can help you.

Node Template:

                <go:SpotPanel.ToolTip>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="Key:" />
                        <TextBlock Text="{Binding Path=Data.Data.GUID}" />
                        <TextBlock Text="   SubGraphKey:" />
                        <TextBlock Text="{Binding Path=Data.SubGraphKey}" />
                        <TextBlock Text="   IsSubGraph:" />
                        <TextBlock Text="{Binding Path=Data.IsSubGraph}" />
                    </StackPanel>
                </go:SpotPanel.ToolTip>

                <go:NodeShape x:Name="Icon" 
                              go:NodePanel.Figure="Circle"
                              Stroke="Transparent"  StrokeThickness="1"
                              Fill="Green"
                              Margin="12"
                              Width="0.01" Height="0.01"
                              go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                              go:Node.PortId=""
                              go:Node.LinkableFrom="True" go:Node.LinkableTo="True" 
                              go:Node.LinkableSelfNode="True" 
                              go:Node.LinkableDuplicates="True" Cursor="Hand"
                              Opacity="{Binding Path=Data.Opacity}"/>
            
            </go:SpotPanel>
        </DataTemplate>

Link Template:

            <go:LinkPanel go:Part.SelectionElementName="Path" go:Part.SelectionAdorned="True" Visibility="Visible"
                      go:Part.SelectionAdornmentTemplate="{StaticResource LinkSelectionAdornmentTemplate}"
                      go:Part.LayerName="Background"
                      go:Part.Reshapable="True" 
                      Background="Transparent"  
                      MouseLeftButtonDown="HandleStreamDoubleClick" >

                            
                <!--Route-->
                <go:Link.Route>
                    <go:Route Routing="Orthogonal" Curve="JumpGap"  
                          FromEndSegmentDirection="RotatedNodeOrthogonal"
                          ToEndSegmentDirection="RotatedNodeOrthogonal"
                          RelinkableFrom="True" RelinkableTo="True" 
                          LinkReshapeHandleTemplate="{StaticResource LinkReshapableHandleTemplate}" />
                </go:Link.Route>

                <go:LinkShape Stroke="Transparent" StrokeThickness="5"  MouseLeftButtonDown="HandleStreamDoubleClick"/>
                <go:LinkShape x:Name="Path" StrokeThickness="{Binding Path=Data.Highlight, Converter={StaticResource theStrokeThicknessConverter}}">
                                           
                    <go:LinkShape.Stroke>
                        <MultiBinding Mode="OneWay"  UpdateSourceTrigger="PropertyChanged"  >
                            <MultiBinding.Converter>
                                <local:StreamColorConverter/>
                            </MultiBinding.Converter>

                            <Binding Path="Data.Data"/>
                            <Binding Path="Link.Diagram.Tag.Network" />

                        </MultiBinding>
                    </go:LinkShape.Stroke>
                    
                </go:LinkShape>

                <!--Arrow Head-->
                <Path go:LinkPanel.ToArrow="Triangle" 
                      go:LinkPanel.ToArrowScale="1"        
                      Margin="2,0,0,0"
                      Stroke="{Binding ElementName=Path, Path=Stroke}" 
                      StrokeThickness="2"
                      Fill="{Binding ElementName=Path, Path=Stroke}">
                    <Path.Visibility>
                        <MultiBinding Mode="OneWay">
                            
                            <MultiBinding.Converter>
                                <local:StreamArrowHeadVisbilityConverter />
                            </MultiBinding.Converter>
                            
                            <Binding Path="Data.Data"/>
                            <Binding Path="Link.Diagram.Tag.Network" />
                            <Binding Path="Link.Diagram.Tag.NetworkHashCode" />
                        </MultiBinding>
                    </Path.Visibility>
                </Path>

                <!--Tin-->
                <TextBlock go:LinkPanel.Index="0"
                           go:LinkPanel.Offset="NaN NaN"
                           go:LinkPanel.Orientation="Upright">
                    <TextBlock.Text>
                        <Binding Path="Data.Data.InitialTemperature">
                            <Binding.Converter>
                                <converters:MeasureConverter DecimalPrecision="1" DefaultMeasure="{StaticResource DefaultTemperature}" />
                            </Binding.Converter>
                        </Binding>
                    </TextBlock.Text>
                </TextBlock>
                
                <!--Tout-->
                <TextBlock go:LinkPanel.Index="-1"
                           go:LinkPanel.Offset="NaN NaN"
                           go:LinkPanel.Orientation="Upright">
                <TextBlock.Text>
                        <Binding Path="Data.Data.FinalTemperature">
                            <Binding.Converter>
                                <converters:MeasureConverter DecimalPrecision="1" DefaultMeasure="{StaticResource DefaultTemperature}" />
                            </Binding.Converter>
                        </Binding>
                    </TextBlock.Text>
                </TextBlock>
                
            </go:LinkPanel>
        </DataTemplate>

Ah, you set the StrokeThickness=“1”. I suspect that would do it. There should be no Stroke. I’m not sure it makes sense to have a Fill either.

BTW, it’s much more efficient to use a simple Rectangle as the only element in the template, than a go:NodePanel containing a go:NodeShape showing a circle. For lots of reasons, simpler is better!

Yep it works. But I need to set width and height at 0.01 otherwise the link is not drawn.

Thank you Walter. Now I got another type of bug, but I will explain to you tomorrow, enought prog. for today :P

Well, I tried to use a Rectangle instead of a NodeShape embedded in a NodePanel and it works, but when I close the form (in which my diagram is) and reopen it, links are invisible until I move a something in the diagram. And I obtain the same behaviour with NodeShape in NodePanel when I set NodeShape.Margin = 0 . When the margin <> than 0, it works.

This template doesn’t work:

            <Rectangle go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"   
                       Fill="Transparent" 
                       go:Part.Movable="False"  
                       go:Part.SelectionAdorned="False"
                       Stroke="Transparent" StrokeThickness="0"
                       Width="0.01" Height="0.01"
                       go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                       go:Node.PortId=""
                       go:Node.LinkableFrom="True" go:Node.LinkableTo="True" 
                       go:Node.LinkableSelfNode="True" 
                       go:Node.LinkableDuplicates="True" />

This template doesn’t work:

            <go:SpotPanel go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"   Visibility="Visible"  
                          Background="Transparent" 
                          go:Part.Movable="False"  
                          go:Part.SelectionAdorned="False"  >

                <go:NodeShape x:Name="Icon"  
                              go:NodePanel.Figure="Circle"
                              Stroke="Transparent"  StrokeThickness="0"
                              Fill="Green"
                             <b> Margin="0"</b>
                              Width="0.01" Height="0.01"
                              go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                              go:Node.PortId=""
                              go:Node.LinkableFrom="True" go:Node.LinkableTo="True" 
                              go:Node.LinkableSelfNode="True" 
                              go:Node.LinkableDuplicates="True" Cursor="Hand"
                              Opacity="{Binding Path=Data.Opacity}"/>
            
            </go:SpotPanel>
        </DataTemplate>

This template works:

            <go:SpotPanel go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"   Visibility="Visible"  
                          Background="Transparent" 
                          go:Part.Movable="False"  
                          go:Part.SelectionAdorned="False"  >

                <go:NodeShape x:Name="Icon"  
                              go:NodePanel.Figure="Circle"
                              Stroke="Transparent"  StrokeThickness="0"
                              Fill="Green"
                             <b> Margin="12"</b>
                              Width="0.01" Height="0.01"
                              go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                              go:Node.PortId=""
                              go:Node.LinkableFrom="True" go:Node.LinkableTo="True" 
                              go:Node.LinkableSelfNode="True" 
                              go:Node.LinkableDuplicates="True" Cursor="Hand"
                              Opacity="{Binding Path=Data.Opacity}"/>
            
            </go:SpotPanel>
        </DataTemplate>

How are you loading the diagram?

BTW, if the port is so small, it will be unlikely that the user will be able to start drawing a link from that object. So I don’t see the point of setting all of those go:Node.Linkable… properties to true.

There’s no point in setting go:NodePanel attached properties if it isn’t inside a NodePanel.

And I wouldn’t bother setting Stroke=“Transparent”, but leave it null.

The links are created programmatically. They were linkable because initialy, I tested it manually. I just forget to set to false this property.

And about the loading of the diagram, I save the model into an object, and when I open a new form, a new instance of the diagram is created, I only set the Diagram.Model property with the model that I previously saved.

OK, in both cases you are creating a new model with new data in it and then setting the new diagram’s Diagram.Model. That rules out some potential initialization issues, but leaves other possibilities.

So one question is if there are any differences in the model between when you create it the first time and when you create it by loading it from somewhere.

No I don’t create a new model, I only created a new Diagram, then i set the Diagram.model property with the model that I had already saved.

So you save the model reference in memory and then set Diagram.Model of the new Diagram?

Hmmm, I don’t know what the problem might be.
If you set the old diagram’s Model property to null before setting the new diagram’s Model property, is the behavior the same?
Do you have an Overview control?
Are you using an UndoManager?

Yep exactly. I tried to set the Model property to null just before setting with my new model but nothing changed.
And also I got no Overview control and no UndoManager too.

Well, I can’t explain it except with the general observation that there might be some code that is modifying FrameworkElements when first building the model/diagram that doesn’t get called when setting the second diagram’s model.

Perhaps you have some side-effects occurring due to the construction or modification of the model or its data? And these side-effects don’t happen when just replacing Diagram.Model?