Catel ui validation

Topics: Questions
Apr 2, 2013 at 11:30 AM
I am trying to implement catel validation. It is a wpf mvvm app, using catel 3.5 and entity framework with my catel mvvm model objects mapped to the EF objects. I have had a look at the catel examples validation project and have a few questions:

First: Which validation strategy to choose; are there any pro and cons to the different strategies? My validation requirements are fairly simple – checking model properties for valid values and\or null\empty etc. Perhaps some business rules to run before hitting the db, pretty straight forward stuff. I have implemented the "Validation in the view model via the validate method" (as per the example project) – this seemed to be the most straight forward\simplest approach. Should I consider using one of the other approaches or even EF validation?

Second: In the example app the IUIVisualizerService is used and the validation hooks into the OK button click. I am not using the IUIVisualizerService to display my user control windows; do I have to use the IUIVisualizerService? I want to validate when a button (Save) is clicked. In the vm code I call the Validate(true) method but the InfoBarMessageControl does not display the errors generated. Any ideas on what I am doing wrong?

Thanks in advance for any help and input.
Coordinator
Apr 2, 2013 at 5:08 PM
1) Depends, but this is mostly a personal preference. In order from simplicity (least flexible) to "complex" (most flexible), this is the order:
  • Attribute validation
  • Overriding the methods
  • FluentValidation
  • Custom IValidator implementation
2) The fact that the UIVisualizerService is used has nothing to do with the OK button. This is functionality of the DataWindow. If you are using a custom window implementation, make sure that you add a WarningAndErrorValidator to the root of your window with the datacontext set to the view model.
Apr 2, 2013 at 8:26 PM
I am using a DataWindow. The DataWindow has a menu and a "Control". A DataTrigger is used to switch between the views.

In the viewmodel constructor I set the DeferValidationUntilFirstSaveCall to true as I do not want the validation to run upfront. The ValidateFields still runs and creates validation errors (for the empty fields) but does not display them (I think this is expected behaviour?). If the Save button is clicked (all fields still empty) and the Validate method run, there are still no validation errors displayed, even though the validation errors exist. I did some debugging into the Catel.Data.ModelBase internal Validate method and it seems that because the "changes" variable is not being populated by the validationContext.SynchronizeWithContext method. I am guessing this is because the errors have not changed from the first validation, when the viewmodel loaded? I can get around this by setting the SuspendValidation to true in the viewmodel constructor and then setting it to false before I call Validate. Seems like a bit of a hak though...

Another question: The validation warnings are appearing at the top of the data window. In my app that puts them above the menu, which does not look right. Is there any way to control the placement of the validation messages? Can I add my own InfoBarMessageControl in my UserControl or even in a separate UserControl and redirect the errors to it?
Apr 4, 2013 at 7:21 PM
I have found a really simple and flexible mvvm validation helper - http://mvvmvalidation.codeplex.com/

This does what I need without getting to complex and seems simple and flexible. I am just not able to get the Catel validation to work as I need it. If you have the time I would suggest having a look at the MVVM Validation Helpers project and consider this implementation for Catel validation?

I did have some difficulty turning off the Catel validation. The InfoBarMessageControl was displaying (when validation error messages existed) even thou I had set SuspendValidationForAllModels = true (I also set HideValidationResults = true and SuspendValidation = true, just for good measure) and the InfoBarMessageControl still displayed. Possibly my hacking at the Catel code has caused this bug. In the end I removed the InfoBarMessageControl & WarningAndErrorValidator from the Catel.mvvm project. I know that sux but it was the only way I could get it to work.
Coordinator
Apr 4, 2013 at 9:57 PM
Are you sure that you have the validation on the views enabled correctly? Like ValidatesOnDataErrors=True, NotifyOnValidationErrors=True?

The ValidationHelper you found seems like the custom IValidator interface implementation that is already provided by Catel, but you are of course free to use that one instead. In other words, that is just what we provide. I don't understand why you are having issues. Did you check out the examples and documentation?

About the InfoBarMessageControl. You can disable the InfoBarMessageControl generation process by a constructor overload in the DataWindow. Then you can put it anywhere you want it to be. As long as it finds a WarningAndErrorValidator as a child it should continue.
Apr 7, 2013 at 7:47 PM
Yes I have definitely set the NotifyOnValidationError=True, ValidatesOnDataErrors=True.

And yes I had a look at the documentation and examples but I just cannot get it to work how I want.

I have tried to create a reproducible example as this might help explain what I am seeing (or not seeing).
ref: https://catel.codeplex.com/workitem/7251
Coordinator
Apr 8, 2013 at 3:49 PM
Works as expected. You should call SaveViewModel() (which is the save call) instead of Validate(true).
Apr 9, 2013 at 6:28 PM
Doh! Yes that works perfectly. Thank u.