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
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 =
TruemIsDeleted =
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
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
>>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
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).
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.)
Thanks Rocky
These changes sound great
I have only just started working with the CLSA 2.x so this information is very helpful
Harv
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 IflintStringLength = Len(CallByName(target, lobjRuleArgsMaxLength.PropertyName, CallType.Get))
If lintStringLength > lobjRuleArgsMaxLength.MaxLength Thene.Description = lobjRuleArgsMaxLength.OriginalDescription & vbCrLf & "The current length is " &
CStr(lintStringLength) & " characters." Return False Else Return True End If End FunctionMike, 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
Harv,
Thanks for the code and information. Much appreciated.
Mike
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
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
>>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