How can I do validation and stop databinding when validation failed?
for example, if a user type 1234 for a firstName texbox which has the following binding:
this.textBoxFirstName.DataBindings.Add("Text", personObj, "FirstName");
Thanks!
Use BindingComplete and/or Parse events of Binding class.
Or use control's validation functionality, which is preferable.
Or use some kind of mask editor. Mask editor would be better from the usability point of view.
Related
I want to validate the datagrid cell namely Item column when the user input against database table itemMaster .My doubt is which method is best for me to validate the input ,ValidationRule or IDataErrorInfo ?
This question is 100% a duplicate. You could have found the answer to this yourself.
Use IDataErrorInfo because then you will be able to validate your input inside ViewModel where you also will be able to access another values/properties/data if needed for your validation.
Futhermore you will be able to swap ViewModels and so change the validation which you will not be able to achieve with ValidationRules easly.
Validation of ViewModel properties should be done in ViewModel. Its centralized and its also testable. It shouldnt not become a part of View except it has to for whatever reason.
You should use ValidationRules when you have binding between two control properties but in this scenario your validation belongs to the "View" anyways and stays inside the View part of MVVM.
I am using WPF, MVVM-Light.
In my UI I have a textbox, and I want to prevent the user from typing certain characters in the textbox.
I know if we use code-behind I could handle the key down keyPress events, can I achieve it through MVVM?
Can we use some behaviors or some interactivity triggers?
Using code-behind is perfectly OK with MVVM providing the code-behind is related to your View only.
So if you have some view-specific logic that says "User can only type numbers in this box", then it's perfectly OK to write a KeyPress event for the TextBox that only allows numeric keys to be processed. You could even throw this into a UserControl so it can be reusable.
However if your allowed character logic is based on application logic, such as "User can only use the characters defined in the app.config file for this string value", then you'd be better off validating that in the ViewModel.
Also note that restriction is different from validation.
If you want to validate a user's entry, then I would do so using IDataErrorInfo from the ViewModel layer, and possibly a binding with a mode of UpdateSourceTrigger=PropertyChanged so the validation is checked after every key press.
If you want to restrict what characters can be typed into a TextBox, then I would probably do that from the View layer in the code behind, as that is a functionality of the View.
Yes, to filter input the MVVM way, I would suggest either using a custom control (such as a masked TextBox control) or a Behavior.
I was recently looking for a good masked TextBox and there is a free one out there from Xceed which you can find here. I can't speak to this one, as I haven't used it, but I've been happy with other Xceed components I've used in the past.
However I didn't want to go third party and include a bunch of controls I didn't need, so I ended up creating a behavior that simply attaches to the TextBox and filters the input based on a FilterType. The behavior is pretty easy to create, and you simply use the PreviewTextInput event to filter out characters that you don't want.
This SO Answer has a number of suggestions and links to how to filter/mask the input and if you're not familiar with creating Attached Behaviors, this example shows how to create an Attached Behavior for a Masked Text Box.
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.
I'm trying to take care with every possible error when a property gets its value through a Binding (MVVM) like being out of a given range.
This is working perfect by using "ValidatesOnDataErrors" in the control I want to check.
The problem comes when I try to check if the given value is accepted by that property in the modelView.
For example, when I write "june" in a DateTimePicker control the binding is broken (the property is a DateTime) so it never gets its value and I can't control the errors the same way I do with the rest of rules.
How should I try this? Is there any solution?
Thanks in advance!!
Solution was really simple!!
If you have a DateTime property binded to a textbox, it's enought to set "ValidatesOnExceptions=True" on Binding instruction from XAML.
If you just want to parse this by youself, you have to use ValidatesOnDataErrors=True and make a validation function to raise a message.
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.