Dotneteers.net
All for .net, .net for all!

Handling WP7 orientation changes via Visual States

VBandi's blog

Syndication

Subscribe

Generic Content

It is pretty well known that an app can be notified of the phone’s orientation changes via the PhoneApplicationFrame.OrientationChanged event. However, if you are as serious about sharing the work between the designer and the developer as I am, you will not be happy with this – the changing of the layout should be the responsibility of the designer, not the developer.

Of course, the best way to achieve the different layouts is via Visual States. You can define two states like this in Blend:

 

image

And move your controls around. For example, in SurfCube V2.2, we wanted to have the tabs and the tab buttons below each other in Portrait mode, but in a totally different arrangement in Landscape.

image    image

In this example, the buttons are placed inside a WrapPanel, and the WrapPanel’s Row and Colums are changed – in Landscape, they are moved to the first column of the second row. You can even throw in some fluid state changes for added effect. This is all nice, but how do you switch between the two states?

The first idea that comes to mind is to use GotoStateActions, triggered by the OrientationChanged event. Unfortunately, you cannot attach an event to the PhoneApplicationPage:

image

(In the above screenshot, the invisible mouse cursor points to the PhoneApplicationPage.)

Even if this worked, we would have problems – the tab page shown above is actually a UserControl, which doesn’t have the OrientationChanged event.

Behaviors to the rescue!

Like so many times before, behaviors are here to save the day. By creating a simple OrientationToStateBehavior (ok, so the name is not so simple), designers can once again have total control over how they want the UI to look in the different orientations. Just attach the behavior to the UserControl:

image

Set up the different states for the different orientations:

image

And that’s it!

As for the code of the behavior, you can find it below.

The most interesting parts are:

  • OrientationChanged is global for the entire phone, so we are using the main application frame for this. However, the root visual may not be available at the time the behavior gets attached, so we enqueue the setup code into the UI thread via a Dispatcher.BeginInvoke code.
  • If you precede your string properties with
    System.Windows.Interactivity.CustomPropertyValueEditor(CustomPropertyEditor.StateName),
    Expression Blend will provide the user with a dropdown menu of the Visual States in the current control.

The rest is pretty self-explanatory, enjoy Windows Phone 7 coding!

   1:  using System;
   2:  using System.Windows;
   3:  using System.Windows.Controls;
   4:  using System.Windows.Interactivity;
   5:  using Microsoft.Phone.Controls;
   6:   
   7:  namespace My3DBrowser.Behaviors
   8:  {
   9:      public class OrientationToStateBehavior : Behavior<UserControl>
  10:      {
  11:          public OrientationToStateBehavior()
  12:          {
  13:              IsEnabled = true;
  14:          }
  15:   
  16:          protected override void OnAttached()
  17:          {
  18:              base.OnAttached();
  19:              InitWhenReady();
  20:          }
  21:   
  22:          private void InitWhenReady()
  23:          {
  24:              PhoneApplicationFrame main;
  25:              Dispatcher.BeginInvoke(() =>
  26:              {
  27:                  main = Application.Current.RootVisual as PhoneApplicationFrame;
  28:                  if (main != null)
  29:                  {
  30:                      main.OrientationChanged += MainOnOrientationChanged;
  31:                      SetState(main.Orientation);
  32:                  }
  33:                  else //If rootvisual is still not set, wait some more
  34:                      InitWhenReady();
  35:              });
  36:          }
  37:   
  38:          public bool IsEnabled { get; set; }
  39:   
  40:          [CustomPropertyValueEditor(CustomPropertyValueEditor.StateName)]
  41:          public string PortraitUpStateName { get; set; }
  42:          [CustomPropertyValueEditor(CustomPropertyValueEditor.StateName)]
  43:          public string PortraitDownStateName { get; set; }
  44:   
  45:          [CustomPropertyValueEditor(CustomPropertyValueEditor.StateName)]
  46:          public string LandscapeLeftStateName { get; set; }
  47:          [CustomPropertyValueEditor(CustomPropertyValueEditor.StateName)]
  48:          public string LandscapeRightStateName { get; set; }
  49:   
  50:          private void MainOnOrientationChanged(object sender, OrientationChangedEventArgs orientationChangedEventArgs)
  51:          {
  52:              if (IsEnabled)
  53:                  SetState(orientationChangedEventArgs.Orientation);
  54:          }
  55:   
  56:          private void SetState(PageOrientation orientation)
  57:          {
  58:              string stateName = "";
  59:   
  60:              switch (orientation)
  61:              {
  62:                  case PageOrientation.PortraitUp:
  63:                      stateName = PortraitUpStateName;
  64:                      break;
  65:                  case PageOrientation.PortraitDown:
  66:                      stateName = PortraitDownStateName;
  67:                      break;
  68:                  case PageOrientation.LandscapeLeft:
  69:                      stateName = LandscapeLeftStateName;
  70:                      break;
  71:                  case PageOrientation.LandscapeRight:
  72:                      stateName = LandscapeRightStateName;
  73:                      break;
  74:                  default:
  75:                      throw new ArgumentOutOfRangeException();
  76:              }
  77:   
  78:              VisualStateManager.GoToState(AssociatedObject, stateName, true);
  79:          }
  80:      }
  81:  }

Posted Mar 08 2011, 04:14 PM by vbandi

Comments

Dew Drop – March 8, 2011 | Alvin Ashcraft's Morning Dew wrote Dew Drop &ndash; March 8, 2011 | Alvin Ashcraft&#039;s Morning Dew
on Tue, Mar 8 2011 17:35

Pingback from  Dew Drop – March 8, 2011 | Alvin Ashcraft's Morning Dew

Handling WP7 orientation changes via Visual States | www.nalli.net wrote Handling WP7 orientation changes via Visual States | www.nalli.net
on Wed, Mar 9 2011 22:31

Pingback from  Handling WP7 orientation changes via Visual States | www.nalli.net

Handling WP7 orientation changes via Visual States | www.nalli.net wrote Handling WP7 orientation changes via Visual States | www.nalli.net
on Thu, Mar 10 2011 3:33

Pingback from  Handling WP7 orientation changes via Visual States | www.nalli.net

Depechie wrote re: Handling WP7 orientation changes via Visual States
on Fri, Apr 1 2011 21:38

Hey Andras... I followed this great guide, but it seems I sometimes don't get all events through?

I do get some triggering, because the canvas get's redrawn, but not always the orientationchanged. Any thoughts?

Here some details: stackoverflow.com/.../wp7-orientation-changing-event-handling

Depechie wrote re: Handling WP7 orientation changes via Visual States
on Fri, Apr 1 2011 22:10

Found the problem... in my landscape visual state there was an extra element in the xaml that caused the problem.

-<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(PhoneApplicationPage.Orientation)" Storyboard.TargetName="phoneApplicationPage">

John Visio MVP wrote re: Handling WP7 orientation changes via Visual States
on Sun, Apr 24 2011 15:59

Is it possible to post a demo app?

Mike wrote re: Handling WP7 orientation changes via Visual States
on Wed, May 25 2011 5:35

I need to resize Textblock controls in a UserControl when the orientatin changes but nothing I've tried works - would this method wotk for a Usercontrol or only for an actual page?

vbandi wrote re: Handling WP7 orientation changes via Visual States
on Wed, May 25 2011 6:31

Mike, it works for a usercontrol (that was the whole point)- you just have to define the states there.

How to handle the orientation in windows phone 7? - Programmers Goodies wrote How to handle the orientation in windows phone 7? - Programmers Goodies
on Sun, Oct 16 2011 3:54

Pingback from  How to handle the orientation in windows phone 7? - Programmers Goodies

Murat Mercan wrote Windows Phone 7 Orientation
on Fri, Nov 4 2011 15:03

Windows Phone 7 Orientation

How do I change the VisualState in WP7 | Jisku.com wrote How do I change the VisualState in WP7 | Jisku.com
on Wed, Oct 17 2012 13:49

Pingback from  How do I change the VisualState in WP7 | Jisku.com

How to manage orientation in Windows Phone using VisualStateManager|qmatteoq.com wrote How to manage orientation in Windows Phone using VisualStateManager|qmatteoq.com
on Mon, Apr 29 2013 15:00

Pingback from  How to manage orientation in Windows Phone using VisualStateManager|qmatteoq.com