electric beach

Christian Schormann

Tuesday, September 1, 2009

SketchFlow: Conditional Navigation Behavior Sample

Yesterday, somebody asked me how to do conditional navigation in SketchFlow. Out of the box, there is no built-in behavior to do conditional navigation, but the good news is that it is not hard to write one. Here is an example for how to do it.

There are many different ways of doing it. For this sample, it works like this:

  • There are two behaviors: SetNavigationTarget and ConditionalNavigation
  • SetNavigationTarget takes one property that you set to the display name of the screen you want to navigate to the next time ConditionalNavigation is triggered. You can have as many of these behaviors as you want across your screen – the last one triggered wins.
  • ConditionalNavigation navigates to the screen set by the last triggered SetNavigationTarget behavior.

Before I explain the code, here is a screenshot of a minimal sample app using them:

CondNav 

The app has two instances of the SetNavigationTarget behavior. One is attached to the LayoutRoot and set to fire right after loading:

DefaultSetTarget

It sets the target screen to “Screen 2”. It is generally a good idea to have one SetNavigationTarget behavior triggered by the Loaded event on every page where you want a default target to be set.

The second instance is attached to the toggle button, and sets the target screen to “Screen 3” when the toggle button is checked.

Finally, the “Navigate!” button on the page has the ConditionalNavigation behavior attached to it, fired by a click of the button.

About the Code

Both behaviors use a little backend object to store state:

   1: public class NavigationTargetStore

   2: {

   3:     private static NavigationTargetStore instance;

   4:

   5:     protected NavigationTargetStore()

   6:     {

   7:     }

   8:

   9:     public static NavigationTargetStore Instance

  10:     {

  11:         get

  12:         {

  13:             if (instance == null)

  14:                 instance = new NavigationTargetStore();

  15:             return instance;

  16:         }

  17:     }

  18: 

  19:     public string TargetScreen

  20:     {

  21:         get;

  22:         set;

  23:     }

  24: }

This backend object is a singleton. That is, an object that can only be instantiated once, and that is accessible through a global static access property. This is a very simple singleton – all it offers is a single string property to store the desired name of the Target screen.

The SetNavigationTarget behavior is also quite simple: Whenever it is triggered, it just stores the string set as its property in the backend object:

   1: public class SetNavigationTarget : TriggerAction<DependencyObject>

   2: {

   3:     public SetNavigationTarget()

   4:     {

   5:         // Insert code required on object creation below this point.

   6:     }

   7: 

   8:     protected override void Invoke(object o)

   9:     {

  10:         // Insert code that defines what the Action will do when triggered/invoked.

  11:         NavigationTargetStore.Instance.TargetScreen = this.TargetScreen;

  12:     }

  13: 

  14:     public string TargetScreen

  15:     {

  16:         get { return (string)GetValue(TargetScreenProperty); }

  17:         set { SetValue(TargetScreenProperty, value); }

  18:     }

  19: 

  20:     // Using a DependencyProperty as the backing store for TargetScreen.  This enables animation, styling, binding, etc...

  21:     public static readonly DependencyProperty TargetScreenProperty =

  22:         DependencyProperty.Register("TargetScreen", typeof(string), typeof(SetNavigationTarget), new PropertyMetadata(""));

  23: 

  24: }

ConditionalNavigation is not really complicated either, but it does have a little twist:

The API function of the player that navigates between screens requires the class name of the screen including its namespace to work. However, this is not the name shown in the SketchFlow Map (you might have renamed the screen, but at the very least, the displayed name is without the name space). In the Invoke() method, there is a little bit of code that walks through all screens present in the prototype and checks if one matches the “nickname” given to the behavior. If it does, the behavior navigates to that screen happily. Otherwise, it does nothing.

   1: public class ConditionalNavigation : TriggerAction<DependencyObject>

   2: {

   3:     public ConditionalNavigation()

   4:     {

   5:         // Insert code required on object creation below this point.

   6:     }

   7: 

   8:     protected override void Invoke(object o)

   9:     {

  10:         // Insert code that defines what the Action will do when triggered/invoked.

  11:         string screen = NavigationTargetStore.Instance.TargetScreen;

  12:         if (screen == null || screen == "")

  13:             return;

  14:         List<Serializer.Data.Screen> screens = PlayerContext.Instance.RuntimeData.Screens;

  15:         foreach (Serializer.Data.Screen ds in screens)

  16:         {

  17:             if (ds.DisplayName == screen)

  18:                 PlayerContext.Instance.ActiveNavigationViewModel.NavigateToScreen(ds.ClassName, true);

  19:         }

  20: 

  21:     }

  22: }

Finally, here is the sample project with the sample source code for the two behaviors:
ConditionalNavigationSample.zip

posted by cs at 14:22  

3 Comments

  1. [...] This post was Twitted by MSExpression [...]

    Pingback by Twitted by MSExpression — September 2, 2009 @ 11:47

  2. [...] more here [...]

    Pingback by SketchFlow: Conditional Navigation Behavior Sample | Silverlight Travel — September 4, 2009 @ 23:52

  3. [...] The Conditional Navigation behaviors enables you to navigate to a different screen based on a TargetScreen variable that is set using events in the interface. [...]

    Pingback by SketchFlow Behavior CheatSheets « ADdendum — September 28, 2009 @ 06:55

RSS feed for comments on this post. TrackBack URI

Sorry, the comment form is closed at this time.

Powered by WordPress

cialis rezeptfrei cialis receta cialis prezzo viagra preis propecia generique levitra donna prix de cialis trouble erection viagra bestellen acheter cialis levitra senza ricetta commande viagra vente kamagra acheter clomid en france cialis bon prix viagra 100 mg acquisto viagra originale viagra donne viagra en ligne sildenafil bestellen cialis venta levitra donne levitra france acheter cialis pharmacie venta viagra viagra acquisto online achat cialis en ligne levitra receta pildoras cialis viagra rezeptfrei viagra recensioni generische viagra viagra te koop trouver du cialis medicament viagra viagra venta libre cialis belgique cialis vente en ligne commande levitra vente de cialis sur internet viagra svizzera viagra preço cialis suisse acheter viagra cialis generico 10 mg trouver du levitra kamagra apcalis curare impotenza procurer du viagra viagra farmacia cialis ricetta medica sildenafil moins cher zyban prix achat de levitra acheter finasteride achete cialis acheter cialis en belgique vardenafil bestellen cialis sur internet acquisto viagra senza ricetta pharmacie en ligne ordina levitra cialis generico comprar cialis em portugal acquisto viagra italia viagra cialis differenze cialis moins cher acheter cialis en pharmacie vendo viagra cialis prix kamagra rezeptfrei achat vardenafil vente viagra viagra vendita on line kamagra kopen comprar cialis generico levitra generico levitra sur le net acheter cialis generique cialis kauf compro cialis compro viagra cialis france levitra 20 mg costo levitra achat cialis generique cialis livraison rapide compro cialis acheter du kamagra viagra sin receta viagra vendita italia tadalafil moins cher cialis prijs viagra 100 mg acquisto viagra net levitra sans ordonnance acheter zithromax acheter cialis internet cialis kopen levitra rezeptfrei levitra farmacia citrate de sildenafil pastilla sildenafil commander du cialis acheter cialis generic viagra naturel generische levitra viagra kosten viagra donna acquistare levitra pastilla levitra impotenza cure cura impotenza levitra venta libre kamagra pharmacie acheter du viagra viagra suisse accutane generique receta viagra levitra pharmacie achat levitra acquista levitra viagra prix viagra europe acheter kamagra oral jelly viagra italia cialis vente libre comprar cialis acheter prozac comprar levitra procurer du levitra kamagra gel venta de sildenafil