Note: Knowledge of MVVM and Binding etc is assumed.
You can download the source from here
At Xamling we work very hard to maintain strict standards and practices during development – one reason we do this is to maintain the best parallel workflows between design and development as we can.
Something that we’ve used extensively in the past with Silverlight is the ability to create DataStateBehaviors, which allow us to bind values from our view model to our visual states. When those values change a VisualState is automatically selected, meaning that we can separate our XAML and code very nicely.
An example might be a view that has two states: UserLoggedIn and UserNotLoggedIn. Depending on the value the VM supplies we want to switch these states.
You could imagine in the past with Silverlight and Expression Blend interactivity stuff, you could do the below:
<Behaviors:DataStateBehavior TrueState="UserLoggedIn" FalseState="UserNotLoggedIn" Value="True" Binding="{Binding IsLoggedIn}"/>
Well after much mucking around tying to keep some semblance of parallel workflows and code that is *not* aware of the view, I decided to bite the bullet and see if the DataStateBehavior could be implemented.
I went on the hunt, and found a number of sites that allow us to replicate behaviors, and using some code pinched from the Expression Blend samples site ages ago, I managed to get it working.
First, the excellent post by Joos van Schaik was a great start, and he even has a nice little library that we’ll use here: http://winrtbehaviors.codeplex.com/.
Grab that, and add it to your project. (there is a copy in the sample, but please see attribution above).
Next, Miguel Fernandes had a great idea to use the BindingListener from the WP7 Prism Phone project on codeplex.
With these two bits, now all I had to do is dig out a class from years ago that was pinched from the Express Blend Samples site, and modify it to work on XAML WINRT.
Once you’ve done that, add a propery to your view model – in the sample the propery is IsLoggedIn. It starts as false, then after 5 seconds moves to true. The sample view model is in ViewModel/SomeViewModel.cs.
I’ve also added a couple of grids to the MainPage.xaml, one for logged in and one for not logged in.
There are two states, once again for the login status.
Finally, I’ve added in the DataStateBehavior itself:
<Behaviors:DataStateBehavior TrueState="UserLoggedIn" FalseState="UserNotLoggedIn" Value="True" BindingName="IsLoggedIn"/>
NOTE: We use BindingName, which is a string unlike the original binding in the Blend stuff, this is because WinRT seems to pass through the bound value, not the actual binding class itself.
NOTE: This only works when the behavior is attached to a control (will not work on FrameworkElements etc like Grid). So bang it on your UserControls.
NOTE: This wont be “Blendable” – i.e. no UI to manage the behavior like in the past 😦
NOTE: Sample is built on VS2012 RTM.
You can download the source from here