How to undo changes in Gonode.UserObject?

Hi, folks!

I use GoDiagram Win 2.0.1 eval

under VisualStudio.NET 1.0 with C#.

My nodes contains reference

to additional data in .UserObject property.

I need to undo/redo changes in additional data

using GoUndoManager.

What’s is now?

First, every node overrides CopyObject member:

public override GoObject CopyObject(GoCopyDictionary env)


MyNode n = (MyNode)base.CopyObject(env);

if (n == null)

return null;

MyData d = this.UserObject as MyData;

if (d == null)

n.UserObject = null;


n.UserObject = wfData.Clone();

return n;


Second, MyData provides correct implementation of Clone member.

Third, every changing of UserObject is implemented as following.

By the way, I don’t know exactly how to call


because there are no suitable example!!

public static bool CallPropertiesDialog(GoView v, GoObject src)


GoDocument doc = src.Document;

if (doc == null)

return false;

bool hasUndo = doc.StartTransaction();

IPropertiesDialogContainer i = src as IPropertiesDialogContainer;

bool result = ( (i == null) ? false : i.PropertiesDialog() );

if (!result) {

if (hasUndo)


return false;


if (v != null) {

v.RaiseChanged(GoDocument.ChangedUserObject, 0,

src, 0, null, GoObject.NullRect, 0, null, GoObject.NullRect);

} else {

doc.IsModified = true;


if (hasUndo)

doc.FinishTransaction(“Edit properties”);

return true;


But MyNode.CopyObject nor MyData.Clone is not called inside this routine

and Undo queue still empty, so that view.CanUndo() returns ‘false’.

Of course, there is “view.Document.UndoManager = new GoUndoManager()” line

at view creation.

Help! I need somebody! © John L.


You need to call GoDocument.RaiseChanged, passing enough information so that an override of GoDocument.ChangeValue is able to actually perform the state change for an undo or for a redo.
There are examples of this, including in the User Guide, in the chapter about Undo And Redo, in the section about Extending GoDocument.

I have this exact same problem.
In the protoapp does NOT add anything to the Undo Queue. Try it, change the location of the file and then try to Undo it. The example in the User Guide doesn’t work.
I cannot get anything to be added to the undo queue.

The Location property is a property that is defined by the GraphDoc example class. I find that I can modify the location in ProtoApp using the Properties dialog, and undo/redo seem to work just fine.
The GoDocument.ChangedUserObject hint refers to the GoDocument.UserObject property, not the GraphDoc.Location property. If you programmatically change the value of a GoDocument.UserObject property within a (completed) transaction, you should be able to undo and redo that change, along with whatever else changed during the transaction.
If you don’t finish a transaction (or if you abort it), CanUndo() and CanRedo() will be false, and calling Undo() and Redo() will be no-ops.

Thanks walter! I was just using “save as” to change the file name which i was not able to undo. The User Guide was a little vague and even deceiving in this area, Pages 124-125 suggest that Property Location was raising the event and causing the undo to be set, when really it was happening somewhere else. Thanks for clearing that up.

Hmm, you’re right–when I modify the GraphDoc.Location using “Save As”, it isn’t undoable.
The reason is the implementation of GraphDoc.Store. You’ll note that it sets the GraphDoc.Location property while GoDocument.SkipsUndoManager is true. I’m not sure why that is, but it makes sense that you wouldn’t want the user to think that the document has been changed just because it has been written out, when that might cause the Location (and Name) to be set.
Anyway, that’s all because of how the example is written, not how GoDiagram is implemented. Maybe GraphDoc.Store shouldn’t be temporarily setting GoDocument.SkipsUndoManager, but should just set GoDocument.IsModified to false (which it also does, already).