GoWPF 3.0.3 - GraphLinksModel with "Single 1-n Links"

Hi i am using the GraphLinksModel for my application, pretty straight forward as it is demonstrated in the sample application.

In the backend with which i must work, there is a single class which represents a node.
And there is a single class which represents a link with 1-n relations. (FromNode and ToNodes)

Is there a predefined sample model class like GraphLinksModelLinkData<string, string> which also supports 1-n links per default? - I need to manually synchronize the UI and the backend currently, and would like to optimize this, since in UI, i have only 1-1 links and in backend i have 1-n links.

I want to achieve, that the operator can make a single link from node A to node B
and i want to achieve, that the operator can make a single link from node C to Node D and Node E.

My thought was, that i make a link, and then i want to drag away another link from that link?
Do you think this is even possible with the current version of GoWPF?

Something like this:
image

Important would be, that Link Y, is a single link. - Which means, when i click it the whole link with all its “ToNodes” Links must be selected as one link.

Many thanks meanwhile, Hannes

The GraphLinksModel would need to have separate link data objects in the GraphLinksModel.LinksSource collection. So loading a model would require constructing the appropriate LinksSource collection from the actual data that you would get. Similarly, saving a model would need to “merge” the data appropriately.

You could customize the behavior so that if you clicked on what is labeled “Link Y” it would actually select both (or all) links. The same goes for deleting and copying and reconnecting a branch (if that is allowed).

I forgot to mention, that i work with MVVM and binding to the LinksSource, so if i understood you correctly, “Single 1-n links” are not supported by the go:Diagramm per default, and i need to handle this on my own, which is okay for me.

And concerning my other question…

Can a link be connected to a link?

Yes, the basic functionality is already built-in: each Link can own a Label Node that is positioned along the path of the link.

Set GraphLinksModel.LinkLabelNodePath so that the model knows that there is a third node associated with a link. GoXam for WPF v3

Here’s an example. It’s fairly old, so it probably doesn’t do exactly what you want:

<!-- Copyright © Northwoods Software Corporation, 2008-2021. All Rights Reserved. -->

<UserControl x:Class="LinksToLinks.LinksToLinks"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:go="http://schemas.nwoods.com/GoXam"
    xmlns:local="clr-namespace:LinksToLinks">

  <UserControl.Resources>
    <DataTemplate x:Key="NodeTemplate">
      <go:NodePanel Sizing="Auto" go:Part.SelectionAdorned="True"
                    go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
        <go:NodeShape go:NodePanel.Figure="Ellipse"
                      go:Node.PortId="" go:Node.LinkableFrom="True" go:Node.LinkableTo="True"
                      Fill="{Binding Path=Data.Color}" />
        <TextBlock Text="{Binding Path=Data.Key}" Margin="8" />
      </go:NodePanel>
    </DataTemplate>
    
    <go:DataTemplateDictionary x:Key="NodeDTD"
                            Default="{StaticResource NodeTemplate}">
      <DataTemplate x:Key="LinkLabel">
        <Ellipse Fill="Blue" Width="4" Height="4"
               go:Node.LinkableFrom="True" go:Node.LinkableTo="True"
               go:Node.Selectable="False" go:Node.Avoidable="False" />
      </DataTemplate>
    </go:DataTemplateDictionary>
    
    <DataTemplate x:Key="LinkTemplate">
      <go:LinkPanel>
        <go:Link.Route>
          <go:Route RelinkableFrom="True" RelinkableTo="True" />
        </go:Link.Route>
        <go:LinkShape Stroke="Blue" StrokeThickness="2" />
        <Path go:LinkPanel.ToArrow="Standard" Fill="Blue" />
      </go:LinkPanel>
    </DataTemplate>
  </UserControl.Resources>

  <Grid>
    <go:Diagram x:Name="myDiagram" Padding="10"
                HorizontalContentAlignment="Stretch"
                VerticalContentAlignment="Stretch"
                NodeTemplateDictionary="{StaticResource NodeDTD}"
                LinkTemplate="{StaticResource LinkTemplate}">
    </go:Diagram>
  </Grid>
</UserControl>

and the C#:

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;

namespace LinksToLinks {
  public partial class LinksToLinks : UserControl {
    public LinksToLinks() {
      InitializeComponent();

      var model = new GraphLinksModel<MyNodeData, String, String, MyLinkData>();
      model.NodesSource = new ObservableCollection<MyNodeData>() {
        new MyNodeData() { Key="A", Color="LightBlue", Location=new Point(10, 10) },
        new MyNodeData() { Key="B", Color="Pink", Location=new Point(210, 10) },
        new MyNodeData() { Key="A-B", IsLinkLabel=true },
        new MyNodeData() { Key="C", Color="LightGreen", Location=new Point(110, 60) },
      };
      model.LinksSource = new ObservableCollection<MyLinkData>() {
        new MyLinkData() { From="A", To="B", LabelNode="A-B" },
        new MyLinkData() { From="C", To="A-B" },
      };
      model.Modifiable = true;
      myDiagram.Model = model;
      model.HasUndoManager = true;

      // background double-click inserts a new node
      myDiagram.ClickCreatingTool.PrototypeData =
        new MyNodeData() { Color="Yellow" };
      myDiagram.ClickCreatingTool.DoubleClick = true;

      // drawing a new link automatically adds a label node
      myDiagram.LinkDrawn += (s, e) => {
        // create and add a label node data for a newly drawn link data
        var labnode = new MyNodeData() { IsLinkLabel=true };
        myDiagram.Model.AddNode(labnode);
        // then associate it with the link data
        var newlink = e.Part as Link;
        if (newlink != null) {
          var linkdata = newlink.Data as MyLinkData;
          if (linkdata != null) {
            linkdata.LabelNode = labnode.Key;
          }
        }
      };
    }
  }

  public class MyNodeData : GraphLinksModelNodeData<String> {
    public String Color { get; set; }
  }

  public class MyLinkData : GraphLinksModelLinkData<String, String> {
  }
}

Thank you walter, solved for me.