GoWPF 3.0.3 - CustomPartManager => OnNodeAdded(Node node)

Hi, in my application i use the GraphLinksModel.

Since i need to adapt to an existing backend, i am in need to synchronize backend nodes and links with the UI nodes and links.

The models NodesSource is ObeservableCollection and LinksSource is ObeservableCollection.

Before i hang on the CollectionChanged event and there i synchronized with the backend, which worked partially.

After diving a bit further into the docs, i saw that i could make a CustomPartsManager, which i did.
I overwrote OnNodeAdded(Node node) and want to use this place, to also add a new node to the backend.

My problem is, that it seems that this is raised multiple times for a single node, which leads to multiple nodes in the backend.

How can i determine, that a node, which actually has been droped on the diagram raised the OnNodeAdded call?

And my current second problem is, that i do not have any location information where the operator dropped the node on the diagram. node.Location always is NaN/NaN ?

Am i using the correct place to synch with the backend? - Also i need to distinct, if a node has been added by drop or if it is a copy paste node.

Many thanks meanwhile, Hannes

Yes, that OnNodeAdded method is called or a ModelChangedEventArgs is raised when the node object is added to the model. Not when the layout automatically assigns the node’s location (if an automatic layout occurs at all – it might only be set programmatically by the app).

I think it would be better to use a model Changed event listener.

model.Changed += model_Changed;

where that function would do something like:

    void model_Changed(object sender, ModelChangedEventArgs e) {
      if (e.Change == ModelChange.CommittedTransaction) {
        UndoManager.CompoundEdit cedit = e.OldValue as UndoManager.CompoundEdit;
        if (cedit != null) {
          // review all of the changes within the transaction
          foreach (IUndoableEdit edit in cedit.Edits) {
            if (edit.ModelChange === ModelChange.AddedNode) {
              . . .
            }
          }
        }
      }
    }

Thank you Walter. - Solved for me.

Just for information, i had to adjust this a little bit in order to work. - Maybe someone needs this in future.

        private void GraphLinksModel_Changed(object? sender, ModelChangedEventArgs e)
        {
            if (e.Change == ModelChange.CommittedTransaction)
            {
                UndoManager.CompoundEdit? cedit = e.OldValue as UndoManager.CompoundEdit;

                if (cedit != null)
                {
                    foreach (ModelChangedEventArgs edit in cedit.Edits)
                    {
                        switch (edit.Change)
                        {
                            case ModelChange.Property:

                                if (edit.PropertyName == nameof(MoNodeData.Location))
                                {
                                    // Update stuff in the backend concerning the nodes location

                                    continue;
                                }

                                if (edit.PropertyName == nameof(MoNodeData.Width))
                                {
                                    // Update stuff in the backend concerning the nodes width

                                    continue;
                                }

                                break;
                            case ModelChange.ChangedNodesSource:
                                break;
                            case ModelChange.ChangedNodeKeyPath:
                                break;
                            case ModelChange.ChangedNodeCategoryPath:
                                break;
                            case ModelChange.ChangedNodeIsGroupPath:
                                break;
                            case ModelChange.ChangedGroupNodePath:
                                break;
                            case ModelChange.ChangedMemberNodesPath:
                                break;
                            case ModelChange.ChangedNodeIsLinkLabelPath:
                                break;
                            case ModelChange.ChangedLinksSource:
                                break;
                            case ModelChange.ChangedLinkFromPath:
                                break;
                            case ModelChange.ChangedLinkToPath:
                                break;
                            case ModelChange.ChangedFromNodesPath:
                                break;
                            case ModelChange.ChangedToNodesPath:
                                break;
                            case ModelChange.ChangedLinkLabelNodePath:
                                break;
                            case ModelChange.ChangedLinkFromParameterPath:
                                break;
                            case ModelChange.ChangedLinkToParameterPath:
                                break;
                            case ModelChange.ChangedLinkCategoryPath:
                                break;
                            case ModelChange.ChangedName:
                                break;
                            case ModelChange.ChangedDataFormat:
                                break;
                            case ModelChange.ChangedModifiable:
                                break;
                            case ModelChange.ChangedCopyingGroupCopiesMembers:
                                break;
                            case ModelChange.ChangedCopyingLinkCopiesLabel:
                                break;
                            case ModelChange.ChangedRemovingGroupRemovesMembers:
                                break;
                            case ModelChange.ChangedRemovingLinkRemovesLabel:
                                break;
                            case ModelChange.ChangedValidCycle:
                                break;
                            case ModelChange.ChangedValidUnconnectedLinks:
                                break;
                            case ModelChange.AddedNode:
                                break;
                            case ModelChange.RemovingNode:
                                break;
                            case ModelChange.RemovedNode:
                                break;
                            case ModelChange.ChangedNodeKey:
                                break;
                            case ModelChange.AddedLink:
                                break;
                            case ModelChange.RemovingLink:
                                break;
                            case ModelChange.RemovedLink:
                                break;
                            case ModelChange.ChangedLinkFromPort:
                                break;
                            case ModelChange.ChangedLinkToPort:
                                break;
                            case ModelChange.ChangedLinkLabelKey:
                                break;
                            case ModelChange.ChangedFromNodeKeys:
                                break;
                            case ModelChange.AddedFromNodeKey:
                                break;
                            case ModelChange.RemovedFromNodeKey:
                                break;
                            case ModelChange.ChangedToNodeKeys:
                                break;
                            case ModelChange.AddedToNodeKey:
                                break;
                            case ModelChange.RemovedToNodeKey:
                                break;
                            case ModelChange.ChangedGroupNodeKey:
                                break;
                            case ModelChange.ChangedLinkGroupNodeKey:
                                break;
                            case ModelChange.ChangedMemberNodeKeys:
                                break;
                            case ModelChange.AddedMemberNodeKey:
                                break;
                            case ModelChange.RemovedMemberNodeKey:
                                break;
                            case ModelChange.ChangedParentNodeKey:
                                break;
                            case ModelChange.ChangedChildNodeKeys:
                                break;
                            case ModelChange.AddedChildNodeKey:
                                break;
                            case ModelChange.RemovedChildNodeKey:
                                break;
                            case ModelChange.ChangedNodeCategory:
                                break;
                            case ModelChange.ChangedLinkCategory:
                                break;
                            case ModelChange.StartedTransaction:
                                break;
                            case ModelChange.CommittedTransaction:
                                break;
                            case ModelChange.RolledBackTransaction:
                                break;
                            case ModelChange.StartingUndo:
                                break;
                            case ModelChange.StartingRedo:
                                break;
                            case ModelChange.FinishedUndo:
                                break;
                            case ModelChange.FinishedRedo:
                                break;
                            case ModelChange.InvalidateRelationships:
                                break;
                            case ModelChange.ReplacedReference:
                                break;
                            case ModelChange.ClearedUndoManager:
                                break;
                            case ModelChange.None:
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }