Doc.IsModified

Hi Walter, I added some properties to the GraphNodes i’m using, and display them in a property grid, when a property value gets changed i need to set the doc.IsModified = true, or at least show the user that something changed and re enable the save buttons. I managed to get that to work on occasion by directly assigning GraphDoc.IsModified, but that didnt work all the time, so i got the brilliant idea of calling a function that will find the start node(beacuse it must be there) and move it slightly then move it back, this works in setting IsModified to true, but for some reason when i save it wont reset to false, in the GraphDoc.Store function, this.IsModified = false; is called but the value never changes. This works fine if i move a node or something around on the document to set the modified state, then save, but it wont work if modified gets set via my cheater function. I figure i’m missing a setting someplace, but cant figure out where.

Thanks
John

I guess a simpler question would be, If i do a GraphDoc.IsModified = true, does anything happen in the background when the value gets assigned, its like its checking to see if there are actually any changes and not allowing me to set the value because it isnt looking at my custom properties for changes. I cant think of any other reason for its behavior because it works perfectly if i move a node around with the mouse, or add something to the document, or change a nodes text. i even changed my cheater function to just move the node 1 unit in some direction and leave it but the isModifed still wouldnt change when i tried to assign it. Is the Document looking for something before it allows IsModified to be changed?

GoDocument.OnChanged sets IsModified to true.
So the question is: do your additional property setters call GoObject.Changed if the value changes?
They should if you want those properties to be part of your document state.

for a setter i just have set{this.SomeProperty = value;}

should i do something like set{ this.SomeProperty = value; GoDoc.OnChanged();} ?

is that event whats preventing me from changed the IsModified bool?

You should implement properties that implement additional state and that you want to participate in undo/redo in the following manner:
public Color CenterColor {
get { return myCenterColor; }
set {
Color old = myCenterColor;
if (old != value) {
myCenterColor = value;
Changed(ChangedCenterColor, 0, old, NullRect, 0, value, NullRect);
}
}
}
To support undo/redo you also need to override GoObject.ChangeValue.
For efficiency, you can call the Changed method differently when your property is an integer or when it is a float or a PointF or a SizeF or a RectangleF. Here are three properties of different types, along with the corresponding override of ChangeValue:
public int Side {
get { return mySide; }
set {
int old = mySide;
if (old != value) {
mySide = value;
Changed(ChangedSide, old, null, NullRect, value, null, NullRect);
// … do any additional side-effects for this GoObject class
}
}
}
public Color CenterColor {
get { return myCenterColor; }
set {
Color old = myCenterColor;
if (old != value) {
myCenterColor = value;
ResetBrush(); // this clears out any cached data that depends on this property
Changed(ChangedCenterColor, 0, old, NullRect, 0, value, NullRect);
}
}
}
public float CenterRatio {
get { return myCenterRatio; }
set {
float old = myCenterRatio;
if (old != value) {
myCenterRatio = value;
ResetBrush();
Changed(ChangedCenterRatio, 0, null, MakeRect(old), 0, null, MakeRect(value));
}
}
}
public const int ChangedSide = GoObject.LastChangedHint + 1;
public const int ChangedCenterColor = GoObject.LastChangedHint + 2;
public const int ChangedCenterRatio = GoObject.LastChangedHint + 3;
private int mySide = Middle;
private Color myCenterColor = Color.White;
private float myCenterRatio = 0.2f;
public override void ChangeValue(GoChangedEventArgs e, bool undo) {
switch (e.SubHint) {
case ChangedSide:
this.Side = e.GetInt(undo);
return;
case ChangedCenterColor:
this.CenterColor = (Color)e.GetValue(undo);
break;
case ChangedCenterRatio:
this.CenterRatio = e.GetFloat(undo);
break;
default:
base.ChangeValue (e, undo);
break;
}
}
This code was actually taken from different example classes and merged together for this forum post.

i tried that but, assuming i didnt screw anything up, it didnt help. undo and redo work fine, and i can get the document to say its modified(by quickly moving a node then moving it back programatically), but i cant get the IsModified value to change when i call the save function. I’m using the same store function that was in flow charter, i do have a slightly older version of the software tho, and when it gets to this.IsModified = false; IsModified’s value doesnt change. The only time that the IsModified = false; works is if the change was caused by me dragging a node w/ the mouse, adding a node, changing the text/name of the node, creating a link, etc… if i do any of those and then save IsModified will set correctly, otherwise it wont set at all.

Does the description in the Remarks section of the documentation for GoDocument.IsModified help?

set{
this.Document.StartTransaction();
int old = getValueFromNum;
if (old != value)
{
this.getValueFromNum = value;
this.Changed(GoObject.LastChangedHint+1,0,old,NullRect, value, null,NullRect);
}
this.Document.FinishTransaction(“GetValueFrom Set”);
}

thats what i’m using to set the value, and it seems to work fine, is this correct, or could it cause some unforseen problems, with the Northwoods built in components.

Thanks Walter

That’s OK, although it’s slightly unusual to have the transaction in a property setter. Normally you just have a transaction around code that is invoked from some event, say from some UI command. (GoDiagram implements transactions for all of the standard behavior associated with GoView mouse and keyboard events, so you don’t have to.) Having the transaction in a property setter implies that you won’t normally be calling that setter on multiple objects in a single command, where one would expect that the whole command be undone or redone as a single step. You can get around this problem by having a transaction surrounding all those setter calls, thereby making all of your setter’s transactions “nested”.
Also, your code assumes that the GoObject is always part of a GoDocument when the setter is called. This is related to your expectation that the setter won’t be called except when the user does something to that object in the view’s document. Of course you can get around this problem by checking if this.Document != null first.

Ok, Thanks for all the help. I knew there was a good reason i keep recommending your companies software to people looking for good 3rd party tools.

John