Silverlight 4 TextBox not validating - c#

We have a SL 4 application utilizing an MVVM architecture and pretty clean data binding between objects and UI controls. We have created a custom ValidationAttribute that we use to decorate our domain classes and to provide field level validation based on a data store. If we utilize these custom validation attributes and manually validate our classes using the Validator class like this:
bool _isValid = Validator.TryValidateObject(this.DataContext, new ValidationContext(this.DataContext,null,null), results,true);
then the custom validation attributes are utilized and everything works fine.
Our issue is that, when simply entering data into a textbox bound to a field decorated with one of these validation attributes we do not see immediate validation feedback (via the default red border and tooltip styling of the tool box).
A sample XAML snippet of a control not validating upon lost focus is:
<TextBox Text="{Binding AssetID,Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=true}"></TextBox>
Any suggestions on what we are overlooking or what we can do to force SL to validate text boxes upon lost focus and not wait until a page level save is done (at which point we just validate with the Validator class)?

You have to validate the value in the property setter of the property you're bound to.
You can see what I mean in this post.
http://msdn.microsoft.com/en-us/magazine/ee335695.aspx
Can you post the property you're binding to, specifically the setter code?

Related

Adding controls dynamically with x:Name in MVVM

In our WPF application, we have a lot of forms with fixed fields. Every form should now be extended with fields the user can define himself. The database contains a table with these user defined fields, each with a label, a type (text, date, numeric, ...), etc.
I have found a lot of great solutions using DataTemplates, there is one issue with this however: it is not possible to generate a unique x:Name property for each field (using the field id for example).
Our application relies heavily on the x:Name property to do things as: show/hide fields, set a mask on numeric fields, move fields, ... All this functionality is read from the database, so a unique identifier per field is needed.
One solution would be to generate these fields with the x:Name in the codebehind (the Winforms way).
Another solution would be to change the functionality that uses the x:Name to using the Tag property.
Before I implement one of these solutions, I want to make sure there is no better way. Is there an MVVM way to dynamically generate fields with an x:Name?
Edit
There seems to be some confusion as to why I would need an x:Name for my fields in an MVVM scenario, so I'll clear it up with an example:
One requirement of our software is that every form field in our application can be set hidden or visible by the user. I'm talking about thousands of fields here. I could have created an property for every field that contains the visibility status and fill it from the database.
Instead, I have created an attached property (attached once in a style) that retrieves the visibility status based on the name of the field and apply it. So this functionality runs separately from the MVVM architecture (I never use the x:Name in the ViewModel). The disadvantage of using the attached property is that the form fields need an identification, being the x:Name property in my case.
Is there an MVVM way to dynamically generate fields with an x:Name
No, there isn't.
x:Name is a XAML directive that is used to uniquely identify a UI element in a XAML namescope and generate a backing field to store the value in the code-behind class of the view.
The view model doesn't and shouldn't know anything about this and it should certainly not generate such elements or backing fields as this would break everything that the MVVM pattern is all about.
If you do require to generate unique names for your UI elements for some reason, you should implement this functionality in the code-behind of the view.
MVVM is not about eliminating view-related code from the views, it is mainly about separation of concerns and testability.

How can I change (i.e. toggle) the bound, StringFormat property of a WPF control?

I have a WPF TextBox that has it's text value bound in XAML. This works fine and, as expected, when the associated value is loaded to the field, it is formatted as desired.
My issue is when the user enters the text field to modify the value, I want to strip away the formatting, and display the raw underlying value.
To do this, I tried to set the BindingExpression.ParentBinding.StringFormat property, on the text boxes binding from within a GotFocus event. However, when I tried to set the StringFormat property to an empty string, I got the following exception:
Binding cannot be changed after it has been used.
So, after a control has been bound to a data model object, is there a straight-forward way that I can modify the string format of the TextBox? I'm willing to change how I format the value of the control, but the end desire is to strip the formatting of the data when it is being edited, and re-instating the string formatting once the user exits the field.
I would probably try it differently. It sounds like you are using the same TextBox for the formatted value and editing the raw value. It would be cleaner to use two different TextBoxes for View and Edit, or package it in a UserControl. Also, I would use two properties, e.g. RawText and FormattedText, and the UserControl would have DependencyProperties with bindings to both properties. The UserControl would automatically switch to the Edit TextBox. The question of "how does the automatic switching" work may be a challenge though. You probably need to use the GotFocus of the View TextBox as you mentioned, although it might not be a bad idea to have an actual Edit button that switches it for you.
I understand about switching to WPF. There is quite a bit of adjustment (aka learning) when switching to WPF. I would think of it as designing a form or control that is "fit for purpose". You don't have to create a new UserControl though. You could do something similar to StackOverflow where there is an Edit TextBox and then the View area, that would be equivalent to the Raw and Formatted values. You would control the Visibility of the Edit TextBox through a BoolToVisibilityConverter when you are in edit mode. Create a public bool IsEditing property on your ViewModel and bind that to the <EditTextBox Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}" Text="{Binding RawText}" ...etc... /> After working with WPF for a while, you really appreciate data binding and it makes it hard to go back to plain WinForms (at least for me - not to say there aren't challenges though!).

Validate UI Control with Model View Presenter (MVP)

I have been using winforms for many years. Normally I write a form and that form, in the code behind does everything (validates user input, communicates with the database…). Recently a friend introduced me to MVP and I have been trying to learn to use it. The problem I am having is replicated some of the stuff I used to be able to do with the form. For example, in the past if I had a textbox and the user entered something invalid in the textbox, I could turn that textbox red, set focus on the textbox and alert the user that they entered something invalid in that testbox. With my validation now being done in the presenter or model layer, I can Messagebox the user that something is not valid but how can I setfocus to a control or change a controls color?
Your presenter holds a reference to the view anyway, so you can just manipulate the widgets (text boxes etc.) directly from the presenter. Or, possibly better, have a method in the view like nameIsInvalid(), where you write your desired behaviour (changing color, setting focus). This method is called when the presenter notices that the input validation has failed.
The validation itself should be done in the model, since that is view-independent.
As always, you don't need to be super dogmatic about that. If it makes sense to have some simple validation associated directly with the widget, then leave it there. But a final validation of the whole form should be handled as I've described above.

Is it possible to validate a Caliburn.Micro input binding

I have a form with some textboxes in them that are bound to their properties in the VM through caliburn's automatic bindings. However if you type something on the textbox that does not make sense for the binding Caliburn simply does nothing with it ( or so I see it as ).
What I want to know if there is a way for Caliburn to constrain input to its binding in someway. For example:
I have a TextBox that is bound to a TimeSpan in the VM.
Writing 00:00:10 works fine and sets the TimeSpan to 10 seconds.
If I would write 00:00:-10 nothing happens and the binding remains at the previous value that did properly bind.
Your issue is not related to Caliburn.Micro that simply helps you connect your view to your view-model using data binding. What you need to use is validation of the data binding. You can read more about data binding in Silverlight in particular the Data Validation section is what you should study.
Caliburn.Micro automatically creates bindings using conventions. However, you may have to customize these bindings in XAML to get the desired validation behavior.
In the case where you write 00:00:-10 your validation fails because an exception is thrown from the binding engine's type converter. If the binding expression for the TextBox has a ValidatesOnExceptions property value set to true you will get visual feedback that the value is invalid. And because the entered value couldn't be converted to a TimeSpan no change is made to the view-model.

doing validation in WPF 4 for non-binding attributes - what approach?

How should one handle validation in WPF 4 when there is no binding? Most of the validation doco I am reading seems to be for controls that have bindings.
For example, just a main windows with some text boxes that a user would fill out, and then a button someone would then click on. One could do it manually I guess but wouldn't' there be a WPF approach for this?
(any short code examples would be appreciated)
I think the most WPF solution would be to create a ViewModel you could bind to, then doing the validation there For example if its a change of password form with an additional "confirm password" field, this won't bind directly to a "user" model with just one password field. So instead create a viewModel with 2 fields "password1" and "password2", databind to these two properties and add representation-specific validation here.

Categories