StrataFrame Forum

Maintenance Form ToolStrip / IsDirty Issue

http://forum.strataframe.net/Topic14990.aspx

By Tim Dol - 3/18/2008

We are having an issue with the Save and Undo buttons remaining enabled after an Undo is performed. The form in question has a 8 business objects. I have double-checked all the form and BO settings. (On the form I have set the IncludeInFormUndoType = All Business Objects)

After the first 'Undo' click, the 'IsDirty' property is remaining True on three of the business objects. A second click will clear everything and disable the Save and Undo buttons.

I have traced through the Undo source code and it appears to be cycling through all the business objects but I can't quite figure out why the IsDirty flag is remaining True.

Any ideas?

Thanks

Tim

By Trent L. Taylor - 3/18/2008

I have traced through the Undo source code and it appears to be cycling through all the business objects but I can't quite figure out why the IsDirty flag is remaining True.

This generally comes from application code handling an event and then setting something back.  There was an issue prior to 1.6.5 on a DateTimePicker control that, under the right conditions, would set a date back to dirty.  So be sure you are on 1.6.5.  Past that, check all of your event handlers to see if you have any logic that will make the BO dirty.

Also, if you look through the RowState of the dirty BO (MyBO.CurrentRow.RowState) you will be able to tell what row is changed.  Next you can look through the Item collection of the CurrentRow to see which field is being changed.  This way you can at least work backwards to see which field is being changed and it might clue you in as well.

By Tim Dol - 3/19/2008

Trent, one of our developers took a close look and the problem we are experiencing and sent me this email. I thought I would pass this on for your comments.

From looking at the StrataFrame source code, it looks to me like the problem is that “Undo” is navigating back to the previously selected record (by calling RestoreCurrentRowIndex) before setting the editing state back to idle.  RestoreCurrentRowIndex in turn calls Navigate.  If you look at Navigate (the one that doesn’t just delegate to another overload of the method), it calls “OnNavigated” after it’s done.  If you look at “businesslayer.events.vb” for OnNavigated, it raises the “Navigated” event, which has a custom event handler (i.e., it doesn’t just call the event handlers that have been hooked in – search for “Public Custom Event Navigated As NavigatedEventHandler”).  This event handler calls “RefreshBoundControls()” (defined back in businesslayer.vb), which calls RefreshControl on each bound control.  Examining this method, it seems that if the business object is not idle, it tries to write the data back from the controls back to the row we just navigated to, thus setting it’s state to modified (A DataRow will be set to modified when written to even if the new value and the old value are the same).

 What I haven’t been able to determine is why this doesn’t always happen. 

By Trent L. Taylor - 3/19/2008

it tries to write the data back from the controls back to the row we just navigated to, thus setting it’s state to modified

It is actually a lot deeper than this...it can get complicated Smile  We have seen this type of behavior before under certain conditions. 

  1. If you have a Trim() on the BO field property
  2. Using a DateTimePicker, Nulls, and a DateTime Field
  3. Dealing with masked data

The only way that I am going to be able to help you really get to the bottom of this is for you to create a small scale sample that reproduces the problem...then we can see exactly where the issue lies.

The problem generally has to do with .NET posting a value back through the .NET data binding.  We actually had an instance in house the other day where this was happening and it ended up being .NET.  But the way we got around it (it was a text box accepting a 2 decimal numeric field) was to assign a BindingFormat (N2 in this case) to the textbox which prevented .NET from updating the value twice.  This was ultimately a .NET issue. 

But any additional details you can provide would be good...you are chasing your tail in the RefreshControl and OnNavigated events.  This logic is not where the issue is...it is actually in the SetValue of the property descriptor through .NET and the actual value getting set.