[Solved] Relinking

Hi,

We are running into some issue using GoXam to allow users to manually link together nodes. Our program has multiple possible models (i.e., Diagram.model objects) from which a user can select. Specifically, a user can select model's name, then the program create a new model from the underlying data in my system, and then we set the Diagram.Model to this model and redraw the diagram. Somehow, doing this repeatedly puts the program in a bad state in which a user's action of linking nodes causes, instead of a relink event, a link deletion and then new link creation.

What might cause this behavior? We're certain it’s a bug in our code, but this link deletion/creation is the symptom. Any tips are greatly appreciated!

We always have a TO node in our links, but the FROM might originally be empty (i.e., "") and relinked to a valid node (i.e., connected up to a valid node0>

· Our custom GraphLinksModel uses the Changed event to synchronize the underlying data model to graph edits

· When the link is deleted (when it should be relinked) our custom Model.Changed event shows the following sequence of events:

o Change[StartedTransaction] * StartedTransaction: Relink

o Change[RemovingLink] ! RemovingLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[RemovedLink] ! RemovedLink: () --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[AddedLink] ! AddedLink: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2)

o Change[CommittedTransaction] * CommittedTransaction: Relink

· However, a normal relink event looks like this in our system:

o Change[StartedTransaction] * StartedTransaction: Relink

o Change[Property] ! Property From: NumberRenderKey-4() --> PrimitiveOperatorRenderKey-16(Input_rhs_2) old: new: NumberRenderKey-4

o Change[ChangedLinkFromPort] ! ChangedLinkFromPort: NumberRenderKey-4() --> PrimitiveOperatorRenderKey-16(Input_rhs_2) new: NumberRenderKey-4

o Change[Property] ! Property FromPort: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2) old: new: Output

o Change[ChangedLinkFromPort] ! ChangedLinkFromPort: NumberRenderKey-4(Output) --> PrimitiveOperatorRenderKey-16(Input_rhs_2) old: NumberRenderKey-4 new: NumberRenderKey-4 Output

o Change[CommittedTransaction] * CommittedTransaction: Relink

· We are creating a new custom model that backs the diagram often, so we’re calling diagram.Model = new OurCustomModel(…) as the user switches between viewing different objects. However, our backing ObservableCollections for nodes and links are not re-created, do we have to cleanup an old model in some way before replacing it with a new instance of our model?

· Following the example code in the GoXamIntro.pdf (page 89, Updating a Database) didn’t quite work for our model for some reason, as none of the e.OldValue objects were instances of UndoManager.CompoundEdit, so we always returned on the last line below. Instead we batch up all edits until we see a committed transaction, then process them all. Any idea why the below doesn’t work for our model?

void model_Changed(object sender, ModelChangedEventArgs e) {

if (e.Change == ModelChange.CommittedTransaction) {

var cedit = e.OldValue as UndoManager.CompoundEdit;

if (cedit == null) return;

Thanks,

Jon

Nevermind, I figured it out. We did need to manually clear references to the shared ObservableCollection<Node & Link> before creating and using a new model. Otherwise I guess the old model still had a reference to the diagram or some other currently used code, it wasn’t garbage collected, and it was causing the issue I saw above.