In a previous post last week I posted a sample for a behavior for conditional navigation by using a global state object. Just a few days later, we got a question on how to represent and reflect user roles (or other global state) in a SketchFlow application. This article shows a simple example how this can be done. There are many possible extensions and variations on this technique, but in this post I can’t do more than show a simple starting point.
The concrete problem the customer wanted to solve is this: A SketchFlow prototype should allow the user to select a particular user role on one screen, and other screens should reflect this choice by displaying UI depending on the role.
In this sample, the idea is to use different Visual States to represent different roles, and some behaviors and triggers to set and act on the state stored.
The sample contains three actions and one trigger:
All of these work together with a simple backend store object that can help to preserve state across screens. The backend store is basically a dictionary that holds a single entry for any given key. The entry can be any object, but the sample behaviors all just use strings for state, because that is enough to store user roles.
This is a little more general than the store used in the Conditional Navigation sample, because it is now possible to store multiple state values by using a different dictionary key (here called GlobalStateTag) for each different state.
You can also think of the GlobalStateTag as a channel, just like on a television set – different channels don’t interfere with each other. The default channel is called “Default”, not very original, I fear…
So, what do the actions do?
- SaveGlobalStateAction lets you save a string into a channel of the global state. It is preset to the “Default” channel, but you can just type in a different GlobalStateTag if you want to use a different channel. Just make sure that all actions that need to communicate with each other use the same channel. You would use the SaveGlobalState action attached to the UI that actually changes the user role – for example, on the “Checked” event of a radio button.
- GlobalStateChangeTrigger can be used with any action or behavior. It is used to act on a change of global state. For example, you could use it with a Property Change action to change a the color of a text block when a state change happens, to indicate that state has changed. You must set a channel and value to match – the trigger only fires when the change happens on the right channel, and when a particular value is set in the state.
- The remaining two actions change Visual State of a screen. They have to be applied to the base screen, or they won’t work. This is a restriction done in the interest of simplicity, but the code could be written to allow the application of the behavior anywhere in the tree. Typically, these two actions would be fired using the Loaded event of the control. But, what do they do?
- The SetGlobalStateAsVisualState action simply takes the string value of the global state and attempts to set it as a VisualState. If there is a VisualState that matches the string value, it is set.
- The MapGlobalStateToState action does pretty much the same, but it lets you translate the string value of a GlobalState to some different Visual State name, which is handy if you already have states on a screen that are named differently
So, how would you use these sample behaviors? Here is an example:
There are two screens, the first to set the state, the second to use it. Let’s look at the first screen first:
See the explanations in the screenshot to see how the actions can be used to set the global state, and to locally react to state changes using the change trigger.
The second screen shot shows an example for how to use the global state:
Again, please see the explanations on the screen shot for how the behaviors are used together with visual states to set UI visibility depending on the global state.
To use the example, just pick a role using the radio button on Screen 1, and then navigate to Screen 2. Navigate back and pick another role, and go to Screen 2 again.
Finally, the example is here: