Why IDataErrorInfo does not catch default messages - wpf

Why my IDataErrorInfo interfaced model validates text but not default windows int validation errors?

The IDataErrorInfo interface validation requires that the input value that is going to be updated to data source should get converted to the source type correctly.So the empty string field cannot be converted to int value correctly, so the source data will retain the original value and the IDataErrorInfo cannot notify the error.
You will need some custom validation rules here.

You can only set an int property to a valid int value and nothing else. It's not the resonsibility of a view model to validate that the view sets the property to an int. The type is part of the view model's API and the contract between the view model and any consuming class including the view.
This kind of validation is performed by the WPF framework itself. If you want to customize it, you could use a validation rule in the view or the control. There is an example available here.
But you can't do anything in the view model (except from changing the type of the property to string but this is generally a bad idea).

Related

Not implementing IDataErrorInfo and yet getting validation

I am using modern UI. I didn't implement IDataErrorInfo at my view model base or any view model, and yet, I get validation error. Namely, when I type in a value in a text box then remove it, I get the error: value '' could not be converted. Also, when I put a break point on the property, I find it holding on to the old value. Thanks
guess: the Type of that property is something non-nullable, like int or double or Color without ?/Nullable modifier. The Binding expression used to bind the control binds directly to the datastructure and lacks a smart converter and lacks a fallback value, so it totally fails to convert an empty string. The UI framework detects the problem and reports the error.
IDataErrorInfo may need to be implemented if you need more complex validations, but that does not mean that no validation and no conversion happens when you don't implement it. Bindings still may fail, as some converter may i.e. throw or return a value of wrong type. Run the app in debug mode and observer Output panel. I bet you will see some reports about failing bindings operations.

Approaches to WPF binding validation?

I'm struggling to find a satisfactory approach to data validation in WPF/MVVM. I've been using IDataErrorInfo but if I bind a textbox to (say) an int property, and enter a non-numeric value, WPF generates its own validation message ("value 'xyz' could not be converted"). The control does get highlighted as being in error, but my viewmodel is unaware that the property is in an invalid state, as the binding (and therefore the IDataErrorInfo validation) never happened.
I haven't looked into custom validators yet. Using these is it possible to notify the view model that there are errors? I'm a bit reluctant to use them as it seems excessive to create validator classes for each of the many rules that a complex application requires. Maybe I could use a mixture of the two approaches, i.e. a basic custom validator that ensures that the input is numeric, and IDataErrorInfo for the more complex stuff?
I'm also struggling to validate "related" properties using IDataErrorInfo. Say my model has "Min" and "Max" properties and I want to ensure that Min is less than Max. If I change the "Min" textbox to be greater than Max, the control would be correctly marked as invalid. If I now change "Max" to be greater than "Min", the "Min" textbox validation state does not get cleared down (presumably because "Min" hasn't changed and therefore doesn't get validated again). What's the best approach for this situation?
I would be interested to know how others have tackled WPF validation. Are there any improvements to WPF validation in .Net 4.5?
Suspect you are aware of this but set never even gets called if the type does not match (or cannot be converted).
Had this problem with an empty TextBox bound to an Int? as the TextBox was passing String.Empty not null. So used a converter to convert String.Empty to null.
A TextBox is going to accept text. There is no getting around that.
You can bind to string so everything gets through to the set.
Or you can handle the keydown event at the UI and only allow numeric and bind to Int. Then in the validation determine if the value is in range.

MVVM detect Validation.HasError in View Model

I'm using MVVM and have most of my validation done using IDataErrorInfo and my ViewModel has an IsValid property which checks the validity of each member that needs to be validated. However I have a couple of textboxes bound to ints that can't be null, so I'm using a ValidationRule to alert the user (with a more friendly message than the "value could not be converted" one) if they blank that field out as obviously the property setter never gets called so the IDataErrorInfo code isn't called.
The problem is that I have a Save button (which is a RelayCommand) which I want disabled if there is any validation error. So the CanExecute of that command checks the VM's IsValid property. But obviously if the user blanks my int field the IDataErrorInfo knows nothing about it and currently the button won't disabled. Is there a way that the ViewModel can detect that error?
I thought I'd found a solution here
http://wpfglue.wordpress.com/2009/12/03/forwarding-the-result-of-wpf-validation-in-mvvm/
but having translated it to C# I can't get it working (the Coerce callback is never called). I don't understand dependency properties and objects very well yet (very new to WPF) and this solution looks complicated to me.
The only thing I can think to do is to get rid of the validation rule and make a nullable int wrapper, put TargetNullValue='' in the binding and then I can check them for null in the IDataErrorInfo code. I would prefer not to do this if there's a better way.
why not use string properties instead of int with IDataErrorInfo validation in your viewmodel? in your savecommand you can safely convert your string to your int values, if IDataErrorInfo has no errors of course. Using string properties with IDataErrorInfo is the most easy way.
edit: one more think, there is another problem if you not use string properties. say you have an int Property, and the user set a 10 in your textbox. so in your viewmodel you have the 10. now the user delete the 10 and set a abc in your textbox. your viewmodel still got the 10., because of the bindingconversationexception. thats why i almost use string properties. to be fair you can use behaviors for textbox to set a mask, so the user can not enter invalid data.
I can think of two strong options right away. One is to bind to a string property in your ViewModel, which in turn is programmed to only parse and store the underlying 'int' value if the string is determined to be valid. This ensures that your TextBox will always successfully store its databound value.
The second is to intercept the ValidationExceptions that occur in your View, storing them in your ViewModel via a custom Behavior. This article will essentially do exactly as you described in your question.
What you can try is BindingGroups and have a validation over the whole element, not just single properties. I used this for our modal dialogs to create a project for example, where certain settings must be set before finishing the dialog. This link explained it in good detail. This one is also quite detailed.

check if value in textbox is valid

I have a textbox with a validator that permits only integer values. How do I check if text in my textbox represents a correct integer value without checking the text itself?
I am using Prism MVVM so I would like to hear some solution like "bind a validator property to your viewmodel/model code", but a generic WPF solution is also fine.
The problem is that I can't get the incorrect value in my model / viewmodel. If the value is incorrect, then the underlying binded property doesn't get set.
You could use IDataErrorInfo, or Data Annotations. The Data Annotations Extensions project contains an Integer attribute.

Event on validation - WPF

I'm looking at developing a simple validation framework for WPF (the IDataErrorInfo method doesn't provide enough info for my needs), and am wondering if there is a way to be notified when a Property is going to validate? Please note that I need to know any time it is going to attempt validation rather than only when there is an error (so NotifyOnValidationError doesn't cut it)
Alternatively, my ultimate goal is simply to package more information than just an error string into my validations (How critical is the error, links for more info, etc.) while still allowing the validation to be driven by the data object (IDataErrorInfo style). If anyone can point me to a method for doing that then I'll be perfectly happy as well. :)
The problem you are going to run into is that WPF databinding and validation are tied to the IDataErrorInfo interface. The bindings check for validation based on the UpdateSourceTrigger property of the binding. So if your binding has "UpdateSourceTrigger=PropertyChanged" then everytime the property changes it calls the item["MyProperty"] which is where you would return information as to whether of not your property is valid. If it's set to "LostFocus" then it checks whenever the control loses focus. The binding also requires the "ValidatesOnDataErrors=True" in order for it to force validation on your bound entity.
I think your best bet would be to create a class that implements IDataErrorInfo and then supply more detailed information based on the severity of the error.
You need to look into inheriting from ValidationRule and then adding the new rule to all you binding objects.

Resources