QuoteReplyTopic: Verification, SLtoolkit-Dataform and the good old FormatException Posted: 02-May-2011 at 4:52am
Hi, i have the following problem (which might not even be related to DevForce...)
In my SL4-MVVM-App with latest DevForceSL, I'd like to check application-wide if there are unsaved entities (works great) or erroneous entities (that's the problem).
DevForce Verification in the Silverlight-Toolkit-Dataform works fine, except for the case where I have a numeric property (eg. typeof decimal), and I insert an alphanumeric value (eg. "500a") in the View's TextBox. A FormatException is thrown by the Dataform, I get the Error displayed in the Dataform (just like a normal Verification-Error) but the value (or the Validation/Verification-Error) is not handed over to the entity in the VM, and (as consequence) EntityAspect.ValidationErrors doesn't change.
The real fun was, when inserting "ValidatesOnExceptions=True, NotifyOnValidationError=True" in the Datafield's Binding, nothing changed. Neither of these events fire: Entity.PropertyChanged, Entity.EntityAspect.PropertyChanged and ((INotifyDataErrorInfo)Entity).ErrorsChanged; Weirdest thing is, if I change the input back to a valid value (eg. from "500a" to "500", ((INotifyDataErrorInfo)Entity).ErrorsChanged fires. I'm completely confused!
Question is: How do I catch the Error in the ViewModel? Is there a recommended way to handle this with DevForce?
By default, System.FormatException that is thrown by DataForm is not sent over to the ViewModel. The exception is being trapped at the View only. That is why you don't see various Entity level events being fired.
If you really want to capture the exception on the VM, you can do one of 2 things:
1. Create an arbitrary string property and bind that to a TextBox. That string property in return can be assigned to the numeric property after your validation.
or
2. Create your own value converter class which you can manage on your VM.
I think you'll realize that this might not be as straightforward as you'd hope so I guess the question is whether you really feel it is necessary to capture the FormatException on the VM.
Regarding the INotifyDataErrorInfo.ErrorsChanged event, that might or might not be a bug. I was able to reproduce the issue here and what I'm seeing is that any kind of property change whether it results in an error or not, will trigger the ErrorsChanged event. This sound incorrect but I will confirm and get back to you as soon as possible.
Well, I don't feel it's necessary at all to capture the Exception on the VM, but those functional specs tell me to, and unfortunately customer's king. ;-)
I think I'll take your first suggestion (arbitrary string prop), because it seems to be at least a bit more straightforward. Especially because I can format the value the way it should be AND localized (which is not possilbe with XAML-inline-StringFormat).
Regarding the ErrorsChanged event: Maybe my quick shot, because i might remember reading something in the Rsrc-Center saying this event does not mean that errors changed, but gives you the ability to by checking the eventargs.
Once again thank you very much!
-Edit:
Ok, after trying I'm stuck again. I added a string-property to my Model and added a DecimalRangeVerifier:
var valOk = decimal.TryParse(value, NumberStyles.Currency, CultureInfo.CurrentCulture, out decValue);
if (valOk) PropertyMetadata.Payment.SetValue(this, decValue);
}
But how do I get the Verification running? I also tried VerifierEngine.ExecuteBeforeSet in the setter and a VerifierException was thrown, but I do not want to throw an exception, obviously I want the Exception to show up in the Dataform. The DefaultVerifierOptions are unchanged, the ErrorNotificationMode is "Notify".
I hope you can help me out of this mess one more time!
Have you made sure the following, "NotifyOnValidationError=true", is set on the TextBox? You also shouldn't need to call VerifierEngine.ExecuteBeforeSet in the setter as the validation is automatically handled.
If that doesn't do the trick, I might have to ask you to upload a small sample solution.
FYI, I did a quick simple example of this to show how it works.
Note: Other unnecessary details are not being shown.
After extensive work on this problem I still got no solution.
Regarding your answer, I tend to say that we do not have the same initial situation.
In my Entity, there is the computed property "Payment", which is decimal. As a workaround, I created the property PaymentFormatted, which is string. If I try to configure my code like you posted, I get errors because I can't set the Payment in the PaymentFormatted-Setter or the other way in the Getter. And I can't set the Payment-PropertyMetadata, as it is already computed.
Maybe you just mixed up the names, so I created a completely independent property "PaymentFormatted" (so your solution, just every "Payment" changed to "PaymentFormatted"). Still the same error.
I even created a new, smaller project, that is easier to oversee, to isolate the problem. But I got the same error. I will upload this sample and send you a message.
Thanks for your help anyway!
EDIT:
@DenisK: It seems that I can't send you a message, your Inbox is full. Could you provide me with your e-mail?
Thanks for the sample. Sorry for the misunderstanding. Yes, my code snippet was only to show how to add a custom property and bind that to a TextBox as well as apply a DF validation to it.
Here's another code snippet that should show how to solve a scenario similar to yours. However, please note that this code snippet is not perfect and could very much be improved depending on your specific needs.
I'm only going to post the Model part of the code as nothing really changes on the View and the ViewModel. And instead of using an Employee entity, I'm now using an OrderDetail entity with UnitPrice decimal property as an example. I also created a custom verifier to have a cleaner control over the validation.
Regarding the INotifyDataErrorInfo.ErrorsChanged event, that might or might not be a bug. I was able to reproduce the issue here and what I'm seeing is that any kind of property change whether it results in an error or not, will trigger the ErrorsChanged event. This sound incorrect but I will confirm and get back to you as soon as possible.
I've submitted a bug report on this. Please reply to this topic should anyone think that this needs to be fixed immediately. Thank you.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum