IValueConverter with MVVMLight on Windows Phone 8.1
I'm currently developing a universal app for Windows Phone 8.1 and Windows store. This time around, I decided to do it right and use an MVVM framework. There are plently good ones to choose from, such as:
I had started using MVVMLight some time ago on this project, so it made sense to look into it more seriously and make use of the right patterns instead of doing "Windows Forms" on Windows Phone. The benefits for using an MVVM/MVC framework are countless and there have been a lot of blog posts written on the subjec. Consequently, I'm not going to spend any time analyzing why this is good practice.
However, as with many other frameworks and toolkits, it's the little things that can "get you". For example, I have a progress bar on a page which is bound to my ViewModel and this works absolutely fine. The progress bar changes as the bound value gets updated. To take it one step further, I also wanted to update the progress bar color based on the bound value. The logic behind it is simple:
As the user creates a new password, I validate the password strength using the open source, public API provided by https://passwordutility.net. You can find more information on this service here. The returned value, which can be any value between 1 and 100, is then passed on to the Progress Bar which is used as a visual indicator of the password's strength. The password strength and corresponsing colors are calculated like this:
- 1-33 - Weak => RED
- 34-66 - Medium => AMBER
- 64-100 - Strong => GREEN
Since the ViewModel is not aware of the UI, as it should be, I need a way to make the UI respond to changes to the value while the user types the password.
Show me the code
As I found out, this can be easily achieved by creating a converter that implements the IValueConverter interface. This little, extremely versatile class, allows you to change the style and output format of most controls based on a specific value. In this case, every time the Progress Bar's bound property changes, I use my custom implementation of the IValueConverter
to change the visual state and style of the Progress Bar. I outline the steps below:
The IValueConverter implementation
First we need to create a class that implements the IValueConverter
interface:
The first 2 parameters are the important ones. The first one contains the value we need to operate on in order to decide which color to use. The second one is the UI Element target. In this case, the target is the Brush which is used to set the Foreground color of the Progress Bar control. The other 2 parameters can also be used to provide additional functionality and logic to the converter.
The resource declaration
Next, we need to register the custom IValueConverter
with our resources. If you don't do this, you wont be able to access the converter in your XAML. Open the file that contains your styles (app.xaml, styles.xaml, page resources etc) and add a reference to your converter. My resources file looks like this:
There are 2 important lines in this file:
xmlns:pd="using:TestApp.Converters"
: defines the custom namespace<pd:BackgroundValueConverter x:Key="BackgroundValueConverter"> </pd:BackgroundValueConverter>
: the reference to the custom IValueConverter implementation
The XAML code
With the class and declaration in place, we can use the IValueConverter in the page XAML to change the foreground color of Progress Bar.
This is where the "magic" happens:
Foreground="{Binding Path=StrengthValue, Converter={StaticResource BackgroundValueConverter}}"
This line binds the foreground color to a specific property in the ViewModel and applies the converter we declared earlier on. That's all we need in XAML to make it work.
The ViewModel code
Finally, we need to add a bit of logic in the ViewModel to check for the password strength value and pass the necessary Brush color back to the View (i.e the XAML page).
We use the MVVMLight notation to create getters and setters for our property and respond accordingly to the IPropertyNotifyChanged
event. When the value changes, we make a call to the UpdateProgressBar()
method. This method calculates the password strength and assigns it to the StrengthValue
property, which is bound to the ProgressBar.
In conclusion, if you're using MVVMLight, it's pretty straightforward to interact with the UI without breaking the MVVM patterns. The IValueConverter
is a powerful tool for developing applications using an MVVM framework and I hope that you've found this post informative to allow you to get started with the IValueConverter.