What we want to accomplish is to keep the GraphSource synchronized with our underlying (executable) data structure - at all times. Hence, when we add nodes we must add a node on our underlying data structure - and vice versa. We have managed to get this working using a number of painful tricks:
1) When our data structure D is updated, we rebuild the GraphSource from scratch and assign it. No performance loss here!
2) When the user modifies the graph using the UI, we keep it in sync with D by overriding the following methods: AddNode(), AddLink(), Clear(), RemoveItem(), RemoveLink()
3) Adding links/connections from UI is a total mess. Since AddLink() is called with no target set, we have to fetch the ConnectionManipulationCompleted event and explicitly modify D from there. Of course, D lives in our viewmodel so we have to dig a bit to get hold of it.
4) To avoid "visual tree" exceptions, we have to modify the UI first, then the underlying data D. I would rather do it the other way around since D should be valid at all times! It could happen that D does not accept a connection and we would then need to further mess up our logic in the ConnectionManipulationCompleted event.
To clarify #4. Today we have the code below. We want to swap the order of the function calls!
public override void AddNode(MyNode node)
Graph.AddMyNode(node.Data); // Might fail!
As you can imagine, all these steps effectively move us away from a clean MVVM design. Either we have too little knowledge to implement this the right way, or your diagram component lacks the ability to nicely accomplish what we want. You tell me :)
Ideally, we would want a TwoWay-binding between GraphSource and D with a nice converter. Otherwise, it would be nice if AddLink() had an equivalent method that was called when the link has indeed been attached so that we can skip the nasty #3 above. #4 is also of interest. Maybe you should pause the updating of the UI while your framework is calling the mentioned functions?