Dragging link's label

Hello ,

I really need as much help you can give me on a matter we discussed a few months ago.

I left the problem, and moved on but now I have to solve it.

If you look at this link you can see what I was looking for: a way to drag\move the text that Is attached to a link

http://www.nwoods.com/forum/forum_posts.asp?TID=4857&KW=simple+lable+dragging+tool&PID=20976&title=link-label-detaching#20976

so I implemented your example and it works well but the side effects are still hard to solve.

I was able to make the label appear on the left side of the link using the offset. But when I start moving the nodes on the link's sides the link's label starts going crazy . I guess the problem lies in the middle point assumption we talked about but I don’t know what to do about it and where to change this assumption.

you suggested to adjust the SimpleLabelDraggingTool to fix such issues but none of the methods runs when the nodes of the link is moving or even in the first time the label is loaded on the link , so I have no idea , what causes the label to move around and how to stop it from happening .

I guess the question is: how (which property) and where in the code can I make the label stop thinking the middle point is what counts and how to make the label return to its original position while moving any of the nodes the link is attached to .

One more thing , I need the label to be near point 0 of the link , meaning near its exit , so for links coming out of the left side of the node the should be aligned to the right of the link and when they exit the right side of a node they should be aligned to the left side of a link.

Here are some visual examples of the issue I'm having:

As I said the label moves freely by pressing ctrl (my implementation) and dragging it. But moving the left or right nodes of the link is making a mess. In this picture you can see, how label is above the cable when the right node is under the link:

While you can see the opposite occurs when I drag the right node above the link (the label jumps below the link like a mad label):

Here you can see how it is maintaining the middle point relation:

Many thanks ,

Leo

First, I want to confirm (and make clear for anyone else reading this) that you are talking about moving a FrameworkElement that is in the visual tree of the Link, not Nodes that are attached to the Link as “label nodes”.

I think you don’t want to make the assumption, as the State Chart sample does, that a label is always a “mid label”. In other words, the State Chart SimpleLabelDraggingTool assumes that you have not set the LinkPanel.Index attached property. But I think you do want to call LinkPanel.SetIndex.

So when the user finishes the label dragging operation, I think you want to find the segment that the label is now closest to and remember that plus the new offset. As it so happens, you can find that code in the Piping sample, in the DropOnto method. The Piping sample uses label nodes, so it has customized the DraggingTool. But the logic for finding the closest segment and remembering the segment fraction and segment offset could be the same as what you want for your tool.

I hope this gives you enough information to implement what you want.

Hi ,

I looked at the piping sample and it seems to be close to what i need , however i am not succeeding to implement it in my case . the code behind and the xaml are too plentiful , and i cant seem to put it all together because of this overhead .
i mean what should i put instead of the textblock that holds the data of the to-be draggable label .
the piping sample’s linktemplate is not containing the text that should go along with the link , instead there are many tricks behined the scene in the code behind…
could you direct me to an easy way to do this ?


im adding a label (text) to linktemplate like this :

<DataTemplate x:Key="LinkTemplate">
    <go:LinkPanel go:Part.Selectable="{Binding IsEnabled, RelativeSource={RelativeSource Self}}"
                  go:Part.SelectionAdorned="False"
                  go:Part.Deletable="False"
                  go:Part.Reshapable="True"
                  go:Part.Movable="False"
                  go:Part.Visible="{Binding Data.IsExpanded, Mode=TwoWay}"
                  go:Part.LayerName="Background"                      
                  Style="{StaticResource EntityStyle}"
                  IsEnabled="{Binding Data.Cable.IsEnabled}">
        <go:LinkPanel.ContextMenu>
            <ContextMenu ItemsSource="{Binding Data.Cable.LinkContextMenu, Mode=TwoWay}"
                         ItemContainerStyleSelector="{StaticResource mainMenuItemContainerStyleSelector}"
                         FlowDirection="RightToLeft"/>
        </go:LinkPanel.ContextMenu>
        <go:LinkPanel.InputBindings>
            <MouseBinding Gesture="LeftDoubleClick" 
                          Command="{Binding Data.Cable.OpenPropertiesCommand}"
                          CommandParameter="{Binding Data.Cable.Data}"/>
        </go:LinkPanel.InputBindings>
        <go:Link.Route>
            <go:Route Routing="Orthogonal"
                      Corner="0"
                      Curve="{Binding Link.Diagram.DataContext.ArchOptions}"
                      RelinkableFrom="False"
                      RelinkableTo="False"  
                      />
        </go:Link.Route>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter">
                <ei:ChangePropertyAction PropertyName="CursorMode" Value="Cable"
                                         TargetObject="{StaticResource CursorHandling}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <ei:ChangePropertyAction PropertyName="CursorMode"
                                         Value="Diagram"
                                         TargetObject="{StaticResource CursorHandling}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>


        <go:LinkShape Stroke="{Binding Data.Cable.ActualStrokeBrush}"
                      StrokeThickness="2"
                      StrokeDashArray= "{Binding Data.Cable.StrokeDash}"
                      />
            <ContentControl go:LinkPanel.Orientation="Along"
                        go:LinkPanel.Index="0"
                        ContentTemplate="{StaticResource CablePortTitle}"
                        Content="{Binding Data}"
                        Margin="15,0,15,0">


                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Data.Cable.CablePort1.Location}" Value="Left"/>
                                    <Condition Binding="{Binding Data.Cable.CablePort2.Location}" Value="Left"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="go:LinkPanel.Alignment" Value="1 0.5"/>
                                <Setter Property="HorizontalAlignment" Value="Right"/>
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Data.Cable.CablePort1.Location}" Value="Right"/>
                                    <Condition Binding="{Binding Data.Cable.CablePort2.Location}" Value="Left"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="go:LinkPanel.Alignment" Value="0 0.5"/>
                                <Setter Property="HorizontalAlignment" Value="Left"/>
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Data.Cable.CablePort1.Location}" Value="Left"/>
                                    <Condition Binding="{Binding Data.Cable.CablePort2.Location}" Value="Right"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="go:LinkPanel.Alignment" Value="0 0.5"/>
                                <Setter Property="HorizontalAlignment" Value="Left"/>
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding Data.Cable.CablePort1.Location}" Value="Right"/>
                                    <Condition Binding="{Binding Data.Cable.CablePort2.Location}" Value="Right"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="go:LinkPanel.Alignment" Value="0 0.5"/>
                                <Setter Property="HorizontalAlignment" Value="Left"/>
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>
    </go:LinkPanel>
</DataTemplate>

the triggers are placing the needed title in the left side or right side of the node(go xam node) ,
and the text lies inside the CablePortTitle
which looks like this :

        <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=Control, Mode=FindAncestor}}"           
                    FlowDirection="RightToLeft">
            <TextBlock Text="{Binding Cable.RequiredPairs}"                        
                       Style="{StaticResource CableTitleStyle}"
                       Visibility="{Binding DataContext.RequiredPairsVisibility, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
            </TextBlock>
            <TextBlock Text="{Binding Cable.TopTitle}" 
                       FlowDirection="LeftToRight"
                       Style="{StaticResource CableTitleStyle}"/>
        </StackPanel>

        <StackPanel Orientation="Horizontal"
                    FlowDirection="RightToLeft"
                    HorizontalAlignment="{Binding HorizontalAlignment, RelativeSource={RelativeSource AncestorType=Control, Mode=FindAncestor}}">
            <TextBlock Text="{Binding Cable.BottomTitle}"
                       Style="{StaticResource CableTitleStyle}"/>
            <TextBlock Text="{Binding Cable.MessuredLength}"
                       Visibility="{Binding DataContext.MessuredLengthVisibility, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
                       Style="{StaticResource CableTitleStyle}"/>
            <!--<TextBlock Text=" מ'"
                       Style="{StaticResource CableTitleStyle}"/>-->
        </StackPanel>

    </StackPanel>
</DataTemplate>

this just formats the string of the draggable (hopefully) label near the specific link