In my application I drag and drop items onto nodes to populate properties of the node. If the item could be added to more than 1 property I create a GoContextMenu for the user to choose the appropriate property otherwise I just populate it.
If a context menu is displayed and the file is saved without doing any other action, Doc.IsModified stays true otherwise it is set to false. Why? (I have tried calling InvalidateViews and disposing the contextmenu but neither works).
Probably because there was some modification made to the document that you didn’t expect. Try setting a breakpoint in a GoDocument.Changed event handler.
Tried that - no good
If I do any other changes e.g move a node, then save, everything is fine
In the debugger id I manually ser IsModified to false it changes back to true!
I assume your document does have an UndoManager. Apparently its GoUndoManager.CurrentEdit property is non-null.
That can only happen due to a call to GoUndoManager.DocumentChanged, which is called when there’s a GoDocument.Changed event.
My code looks like this
In GraphViewVindow Save
this.Doc.SuspendsUpdates = true;
this.Doc.SkipsUndoManager = true;
this.Doc.Store(file, loc);
this.Doc.SuspendsUpdates = false;
this.Doc.SkipsUndoManager = false;
If a ContextMenu was the last thing displayed then IsModified is true else it is false at this point in the code.
Why do you temporarily set SuspendsUpdates and SkipsUndoManager?
So you had set a breakpoint in a GoDocument.Changed event handler before bringing up the context menu, right?
I think you misunderstand the order of operations
The user drags a tree entry onto a node. If the user gets prompted with a context menu, chooses a menu entry then saves the document IsModified stays true. If the user does not get prompted with a context menu then saves the document IsModified changes to false (as expected).
If the user gets prompted with a context menu, chooses a menu entry,moves the node and then saves the document IsModified changes to false (as expected).
The Changed event handler does not get called during the save process. I added the SuspendsUpdates and SkipsUndoManager code just to make sure the doc doesn’t get updated during save.
Oh, now I understand what you are doing. OK, so setting SuspendsUpdates and SkipsUndoManager really is superfluous.
So is that the context menu brought up in a GoView.ExternalObjectsDropped event handler?
All such event handler delegates are called within the transaction that the GoView defines for handling the drop. It is fairly common to want to modify the just-dropped objects, so such modifications need to be part of the transaction that surrounds the GoDocument.CopyFromCollection that implements the typical drop. Otherwise, for example, an Undo would just undo the modifications, but not the copy caused by the drop. That would be very confusing, at the least, for users.
But during the transaction, the GoUndoManager is of course recording the changes that are taking place. Those are held in GoUndoManager.CurrentEdit. And while such changes are occurring, GoDocument.IsModified should be true.
Now it turns out that when you set IsModified to be false at this time, it does clear that internal flag, but the IsModified property continues to return true because of the presence of those ongoing changes held in GoUndoManager.CurrentEdit.
So it seems to me that when saving the document from the context menu, once the context menu is dismissed and the transaction has ended, GoDocument.IsModified should indeed be false again. After all, before moving a node, isn’t saving the document disabled? That would be because IsModified is false.
Still not quite gotmy problem. I don’t save the document during the contextmenu operation (yes it is part of GoView.ExternalObjectsDropped) but if the user saves it as the first operation after the dragdrop then isModified stays true.
It is like the view is marked invalid and need refreshing and resets IsModified.
Wait, I still don’t understand the situation you have.
Are you saying that if in the debugger, you look at GoDocument.IsModified after the drop is finished and after the context menu is gone and after the user saves the document as a separate command, the value is true?
Or is it just that the UI needs to be updated, even though the value of GoDocument.IsModified is false as it should be?
Yes ,after the drop is done and the context menu is gone and after the user saves the document IsModified is still true.
So the only difference in your two scenarios is that when a context menu is shown and dismissed, saving the document does not cause IsModified to become false, but when the context menu is not shown, saving the document does cause IsModified to become false?
Hence we need to figure out what about showing a context menu might cause a problem. It’s hard to believe that showing a WinForm component, which has nothing to do with GoDiagram, would have this effect.
In fact, is there any GoDiagram code or state involved in showing the context menu or dismissing it? If so, what does that code do? Do you start and finish any GoDiagram transactions?
I change a property of the node and set a status message.
In DoExternalDragDrop I start a transaction and finish the transaction but not in the cmenu event handler
I will check that the Start and Finish transactions match up.
What happens when the user is shown the context menu but the user does not click on any menu item and the menu goes away?
That is OK
Should I put the EndTransaction in the contextmenu handler?
What happens when the user clicks on a menu item that doesn’t do anything?
Within the ExternalObjectsDropped event handler, you don’t need to start or finish any transactions. After all, if there weren’t any event handlers, the transaction would occur normally. But starting and finishing (a nested transaction) is OK. And mismatched transaction calls are a bad idea.
I moved all the start and end transaction calls to directly around the code that changed properties - SUCCESS
Thank you for your patience in helping me work this one out.
Now if I could just solve the undo subgraph collapse problem I would have no known bugs!
Solved my undo collapse bug too - wasn’t calling the base ChangeValue method
Hurray!
Is there a way to remove the eventhandlers for the GoView context menu? Like I want to have a version of my diagram that users can edit and one that they can only view. I don’t want them to be able to drag anything or right-click and get a context menu.
If you have an override of GoObject.OnContextClick or GoObject.GetContextMenu, you can look at the GoView argument to decide whether to do or return anything, and if so, what to do or return.
Selection is per view. To select a document object, call GoView.Selection.Add on the desired view.