Silverlight Validation Problem - silverlight

I have a Silverlight control which has a ListBox showing a series of email addresses. The data source is an ObservableCollection of strings (one per email) in the ViewModel. Simple enough!
I wanted to allow in-place editing of the list, by changing the data template from a TextBlock to a TextBox, with a two-way binding.
The problem is this: How do I validate the user edit is a valid email address?
I don't want to save the bound text to the list unless it's valid. I can't throw an exception as it's bound to a string, so there's no Set method to modify.
The only solution I can think of is to create a dummy class with a single Email property just so I can validate the value. I can't believe that's the best way.

Well you've got bigger problems than just the validation. You can't use TwoWay binding when the source object is a string.
It does make some sense to create an AddressEntry class that has an EmailAddress string property. That way you can make two way binding work and it gives you somewhere to write your validation.

Related

wpf Datagrid :which Validation method is best for datagrid

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.

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.

Datagrid Edit mode and data validation via service

I got a datagrid(dg) which is bound with an observable collection of POCO [Name(string), value(int), isReady(bool)]
I need to let the name being editable so my DataGrid has <data:DataGridTemplateColumn.CellEditingTemplate> wich contains a TextBox.
when committing the edit, I need to call a WCF Service to validate the name. That's what I am doing in CellEditEnded.
But when the name is not valid, how can I:
Display an error on the datagrid (searching a solution with ValidatesOnNotifyDataErrors but can't succeed)
Put the cell back in edit mode.
Here's why I can't validate in the POCO:
DataGrid is in edit mode
By double clicking on a cell, the label containing the data becomes a TextBox. I'm now in edit mode
I insert an error. An assynchronous validation is launched. DataGrid is back in display mode
the assync is finished, I raised my error, but nothing happens (visually I mean) because ValidatesOnNotifyDataErrors does not seems to work on label.
And more, as I know there is an error, if I enter back in edit mode, I get a really strange display telling there is 1 Error and when enterring this state, I can't get out of edit mode, whatever I do...
Thx
(sorry for my bad english)
I would recomend that you do not use the grid event to validate your data - do this on your POCO properties setter - its cleaner, easier to mantain and if you use this POCO with another control your validation will still work.
Since you need to access a service to validate the value, your best bet is to implement the interface INotifyDataErrorInfo, that allows you to make asynchronous validation, look here: http://weblogs.asp.net/fredriknormen/archive/2009/11/22/silverlight-4-and-asynchronous-validation-with-inotifydataerrorinfo.aspx and here http://www.silverlight.net/learn/data-networking/validation/asynchronous-data-validation

WPF : Nullable ComboBox

I want to have an empty item in the comboBox to allow the user to "Unselect" and keep the comboBox empty (Null value).
How can I do that?
Make your life easier by using a sentinel value. That is, an instance of your view model class that represents nothing.
If you take a look at my blog entry here, you can see a binding solution that doesn't require you to "modify" your VM or to add dummy items into a collection that doesn't really fit with your data.
Basically, you use a CompositeCollection in your XAML, which gives you the ability (for instance) to have numeric values in your combo-box, and the text "Please select..." to designate the place holder, which you can't do if you are binding entirely to numeric fields in your model and relying on that to add this magic value.

Resources