Where to put sync code


I’m having so trouble to know where exactly I should put the code that updates my business model when the user makes some modifications in the graph. Here are my candidates:

  • In the GoDocument.OnChanged event. Apart from the fact that I could
    not find any documentation that explains what I might find in the
    parameters of this event depending on the hint/subhint, I’m afraid that
    using this may make me enter into a bad loop: I get some external
    update on my model, therefore I update the diagram, then I receive some
    update notification, then I update my model again. Am I right ?

  • In the events of the GoView, for instance GoView.LinkRelinked. The problem is that I’m not sure those events get all the required data to perform the update. For instance, GoView.LinkRelinked get only one parameter, of type GoObject. I guess this object might be a GoLink (once again, the doc is rather elliptic), but in order to handle such an event, I also need to know where the link was connected before.

  • In the tools that enable me to make the changes. This feels rather clumsy, and error prone. You can never know for sure you have not forgotten one way the user might modify the diagram.

What would you advise me to do ? Is there anything I missed ?

Best regards,

Yes, you do need to be careful about making changes to the document in a GoDocument.Changed event handler. However, it is commonly done, and fairly safe, if you don’t make the “same” kind of change as a result of a change.
Furthermore, if you also implement your mutators (such as property setters) so that they do not call GoObject.Changed or GoDocument.RaiseChanged unless there really is a change, you can avoid a lot of problems. That’s why you’ll see a lot of properties implemented by having the setters compare the old and new values first–only if the new value is different is the field set and the GoDocument.Changed method called.
Finally you can easily keep a flag or other additional state around so that you know “why” some change is happening. If you have implemented modeless forms that reflect the current values of some object(s), you may have done this too: keeping track of whether the user modified some control and thus the internal data needs to be updated, or whether the internal data was changed and thus the form’s controls need to be updated.
You can get documentation on what hints there are in the documentation for GoDocument.RaiseChanged and GoObject.Changed.
Yes, you can get the relevant GoObject from those events where that would make sense. To avoid a profusion of EventArgs classes, we tried to share them where we could. For other cases, you might need to look at the GoView, such as at the GoView.Selection, or at other properties of a GoView or its tools.
Modifying a tool is the most general thing to do. Many of the higher-level events for a GoView are easier well-defined ways of customizing predefined tools without having to override tool methods and replacing the standard tools.
For business model changes, perhaps another way would be to implement a GoDocument.Changed event handler for the FinishedTransaction and perhaps FinishedUndo and FinishedRedo cases. You can then scan all of the changes that happened during the transaction, and decide what you want to do.
There’s an example of this in a new sample application, UpdateDemo.

Thank you for this information, and especially for this new sample, it seems really instructive. I’ll have a deeper look at it and come back to you if I have further questions.