Determine if changed since new

Determine if changed since new

Old forum URL: forums.lhotka.net/forums/t/502.aspx


Michael Hildner posted on Wednesday, June 28, 2006

Hi,

Is there a CSLA way to determine if an object has been modified after it was created?

I want to present my users with a "Do you want to save changes?" dialog when they close the form. I was basing this on .IsDirty. An object is dirty when it gets created, but if a user doesn't modify the new object, I shouldn't ask them to save.

Thanks,

Mike

matt tag replied on Wednesday, June 28, 2006

At the end of the DataPortal_Create(), call MarkClean.  This way, if the user makes no changes, IsDirty=false, and you don't have to worry about saving.

matt tag

ajj3085 replied on Wednesday, June 28, 2006

Not any way within the framework; you could create a bool in your form and default it to false.  Then handle the objects propertychanged event and set the bool to true.  If the bool is true, you know they modified the object since it was created.

Will that work for you?
Andy

HarvDotNet replied on Wednesday, June 28, 2006

In CSLA 1.x

BusinessBase.vb

----------------------------------------------------------------------

 

' This has been changed by the COS Small Systems Group

' Originally it was initiallized to True, but we want New objects to not be dirty

' It should have been changed along with the change in the MarkNew procedure

' 2004/08/10

Private mIsDirty As Boolean = False

 

----------------------------------------------------------------------

Protected Overridable Sub MarkNew()

mIsNew = True

mIsDeleted = False

'This has been commented out by the COS Small Systems Group

'2004/07/06

'MarkDirty()

End Sub

----------------------------------------------------------------------

 

Protected Sub MarkDirty()

' This has been changed by the COS Small Systems Group

' When the object first becomes dirty, check all of the rules

' Harv Sather

' 2006-03-01

If Not mIsDirty Then

'The Object must be marked dirty, or most rules will not fire (Harv Sather)

mIsDirty = True

 

'Check all of the broken rules for the object

BrokenRules.CheckRules()

End If

 

-------------------------------------------------------------

I have made a similar modification in CSLA 2.x

 

HTH

Harvey Sather

Saskatoon, Canada

 

 

 

HarvDotNet replied on Wednesday, June 28, 2006

We have set up most of our business rules so that they do not trigger until the object is dirty.

The reason is that we display a red ErrorProvider next to any field for which there is a broken rule.

We do not want to display the ErrorProvider until the object is actually dirty.

-----------------------------------------------------

In addition, we have a base form which we inherit from

In the base form, we have a function to check if the object is dirty, and to display a message asking the user if they want to save their changes

This is in a messagebox

Yes | No | Cancel

Yes saves, if the object is savable (dirty and valid)

No discards all changes

Cancel returns the user to the form so they can continue editing, etc.

 

The function is called from the derived form, in its Closing event, so it gets called even if the user just clicks on the x in the top right corner, (or uses Ctrl-F4, etc)

 

Harvey Sather

 

Michael Hildner replied on Wednesday, June 28, 2006

>>We have set up most of our business rules so that they do not trigger until the object is dirty.

>>The reason is that we display a red ErrorProvider next to any field for which there is a broken rule.

>>We do not want to display the ErrorProvider until the object is actually dirty.

Hey Harvey,

I like that idea. Do you mind clarifying how you set that up? I'm trying to figure out the best way to not have business rules fire unless the object is dirty.

This is kinda related. If you don't check rules right away, how do you handle showing the ErrorProvider when you have a StringRequired rule and the user just tabs through the text box?

Thanks,

Mike

 

RockfordLhotka replied on Wednesday, June 28, 2006

Harv,

I did change MarkClean() to be protected in version 2.0, with the idea that it would be possible to alter the business object code rather than the framework. Since you can now call MarkClean(), you should be able to accomplish your goal without altering the framework code.

Just call MarkClean() any time the object is new (in the constructor and after any MarkNew() call).

RockfordLhotka replied on Wednesday, June 28, 2006

Also, to answer the original question - consider that PropertyHasChanged() can be overridden, thus allowing you to add extra functionality/processing when a property changes. This would allow you to implement your own "dirty" flag with different meaning from the standard CSLA one.

(it also is a great place to handle field-by-field dirty tracking, or to implement more complex ideas like having a property only be dirty if it differs from its original value, etc.)

HarvDotNet replied on Thursday, June 29, 2006

Thanks Rocky

These changes sound great

I have only just started working with the CLSA 2.x so this information is very helpful

 

Harv

 

HarvDotNet replied on Thursday, June 29, 2006

Mike

Here is our generic rule for Maximum string length

We have created a number of derived RuleArgs to work with different types of rules

This one is called RuleArgsMaxStringLength and contains a property to indicate the maximum length allowed

 

' Maximum length rule for strings

' The description is set in the call

Public Shared Function MaximumLength( _

ByVal target As Object, ByVal e As RuleArgs) As Boolean

Dim lobjRuleArgsMaxLength As RuleArgsMaxStringLength = CType(e, RuleArgsMaxStringLength)

Dim lintStringLength As Int32

 

'This is where we check to see that the object is or is not dirty and return a True if it is not dirty

If Not CBool(CallByName(target, "IsDirty", CallType.Get)) Then

Return True

End If

lintStringLength = Len(CallByName(target, lobjRuleArgsMaxLength.PropertyName, CallType.Get))

If lintStringLength > lobjRuleArgsMaxLength.MaxLength Then

e.Description = lobjRuleArgsMaxLength.OriginalDescription & vbCrLf & "The current length is " & CStr(lintStringLength) & " characters."

Return False

Else

Return True

End If

End Function

HarvDotNet replied on Thursday, June 29, 2006

Mike, in answer to your second question

If you have a look at the 4th post above, check out the MarkDirty Sub

In particular, this part

-----------------------------------------------------------------------

If Not mIsDirty Then

'The Object must be marked dirty, or most rules will not fire (Harv Sather)

mIsDirty = True

 

'Check all of the broken rules for the object

BrokenRules.CheckRules()

End If

-----------------------------------------------------------------------

What this does is to check all rules the first time the object is marked dirty

That will ensure that your required field rule is checked.

If the user later tabs through it, no rule will fire, but the rule has already fired by some other property being changed, the object being marked dirty for the first time, and all rules being checked because of this.

If the user than changes the value,, or in this case enters a value in the text box, the rule will become valid.

HTH

As Rocky pointed out, this can all be handled a little easier in CSLA 2.x

Harv

 

Michael Hildner replied on Thursday, June 29, 2006

Harv,

Thanks for the code and information. Much appreciated.

Mike

Q Johnson replied on Wednesday, June 28, 2006

Exactly, you tie the Save warning machinery to the .IsDirty property.
 
It SHOULD ask them to save if the object is new to them - it doesn't exist in the database yet - or it never will get persisted there.
If they've opened an EXISTING object (from the DB), it WON'T be dirty - until they make a change.  So there isn't a need to warn in that case.
 
Make sense?


From: Michael Hildner [mailto:cslanet@lhotka.net]
Sent: Wednesday, June 28, 2006 3:14 PM
To: QJohnson@TeamNFP.com
Subject: [CSLA .NET] Determine if changed since new

Hi,

Is there a CSLA way to determine if an object has been modified after it was created?

I want to present my users with a "Do you want to save changes?" dialog when they close the form. I was basing this on .IsDirty. An object is dirty when it gets created, but if a user doesn't modify the new object, I shouldn't ask them to save.

Thanks,

Mike




HarvDotNet replied on Wednesday, June 28, 2006

Q...

Try creating a new Excel spreadsheet, don't make any changes, and then close it

You will not be asked if you want to save it.

This is the behaviour that is desired in a CSLA object as well.

 

This topic was discussed as some length in the old forum

Harv

 

Michael Hildner replied on Wednesday, June 28, 2006

>>It SHOULD ask them to save if the object is new to them - it doesn't exist in the database yet

That's not the user experience I'm looking for. Think of Microsoft Word. If you open a new document, don't make any changes and close the app, it doesn't ask you to save.

I like the idea of marking as clean, but I'm not sure if I should put this in the business object or the UI code. Seems like it's UI specific.

Mike

 

Copyright (c) Marimer LLC