NGTweet Part 8 : Silverlight Validation using IDataErrorInfo

 

In the previous post I demonstrated decoupled communication between view models using Messenger. In this post I intend to demonstrate the validation feature available out of the box in Silverlight. In any application which allows users to input data there is a need to validate the data to ensure that the data is in valid state. If you have used Twitter, you must be aware of the fact that Twitter has a restriction on the number of characters that can be used in a status message. This is restricted to 140 characters. In this example we will use this restriction to validate the status message in the compose section.

Make changes to the ViewModel

There is a built in Validation API available in WPF and Silverlight. We can leverage this to easily incorporate validation logic in our application. Both Silverlight and WPF offer an interface named IDataErrorInfo. This interface has a single Error property and an Indexer. Lets implement this interface on our TweetActionViewModel.

        public string Error

        {

            get

            {

                return null;

            }

        }

 

        public string this[string columnName]

        {

            get

            {

                switch (columnName)

                {

                    case "TweetText":

                        if (TweetText.Length >= MAX_CHARACTERS)

                        {

                            return "You have exceeded maximum character limit of 140 characters.";

                        }

                        break;

                    default:

                        return string.Empty;

                }

 

                return string.Empty;

            }

        }

You can see from the above code that I did not implement the Error property. I just return null. This is property can be used to show a global error message. But in my case I would like to show a contextual error message highlighting the field which caused the error. That is the reason I have implemented the Indexer. The indexer taken the string parameter which is the name of the property. I am interested in validating the TweetText property. So I check the length to see if its within the valid bound. If not I return a string message indicating the error.

The way this works behind the scene is, based on the data binding, when the TweetText property is updated in the UI, the view model raises the property changed notification. This causes the UI control to update its binding. With some additional attributes in the data binding section we can ask the binding infrastructure to validate the data for us. The UI triggers the call for the Indexer and if there is any error highlights the associated controls on the screen. The final impact is similar to what we get to see in an ASP.NET MVC application when the model validation fails.

Make changes to Data Binding in View

As mentioned above, we need to modify the data binding for the view so that the data binding infrastructure triggers the call for the accessor.

<TextBox Text="{Binding TweetText, Mode=TwoWay, ValidatesOnDataErrors=True}"
                        UseLayoutRounding="True"
                        TextWrapping="Wrap"
                        Height="100"
                        Width="300"
                        Margin="5"
/>

Please note the additional attribute ValidatesOnDataErrors specified in the binding expression. Once we have this attribute in place, the moment we enter more than 140 characters in the status text box and fire the update by tabbing out, binding takes care of validating the input. If the text is more than 140 characters, automatically a red border appears around the text box.


error message


There is also a small indicator attached to the top right corner. When the user hovers over this  the error message is displayed.


error message display


This is particularly helpful when there are dependent properties and changes to one property causes error in more than one property. Instead of showing the error message one by one to the user, all the invalid controls can be highlighted at once.


 


Conclusion


I hope this example was good enough for demonstrating the built in validation API using IDataErrorInfo interface. This interface can be really handy when we have a data entry for with many fields. We can use it to pre-validate the fields. Suppose there are 20 user interface controls and the form needs 5 of them to be filled in. Even before user has entered anything, these 5 controls can be in invalid state and hence the user will be able to know which are the mandatory fields on a particular screen.


As always the complete working solution is available for download.


Until next time Happy Programming Smile

Share:
spacer

No comments:

Post a Comment