How do you rotate your WP7 pages/change orientation?
Sunday, February 19, 2012 4:58 PM
I love to see apps which support orientation changes, but how do you do it? Better yet, how do you do it ALL in XAML? I have some code and XAML to start you off.
Take your WP, open up your favourite app, now rotate your phone, ya, physically turn it sideways, try it…did the app rotate too? If you’re wondering “how the heck did they do that?” well I think I can help you replicate that behaviour yourself in YOUR OWN code. I have four sample projects, and they take you from nothing (to see what you get for free with the OS) through doing the orientation change in code to going sans-code and having it ALL in XAML! “Look Ma! No code!” HAHA
All of my examples are of a simple three button layout with text underneath. The ideal UI would have all the buttons visible all the time. Therefore, when in portrait mode, I would like the buttons vertical. In landscape mode, the buttons should be horizontal.
1. What do you get for free…what’s in the OS to help you out?
In the first example, the ONLY thing I changed is the SupportedOrientations="PortraitOrLandscape" of the MainPage.xaml file. Notice how things are good for portrait, but landscape does nothing other than rotate the buttons. You can’t see all the buttons, layout is still vertical, you can’t see the TextBlock at the bottom AND there’s a lot of wasted space. This is a perfect example of “rotating” the stackpanel to a horizontal layout would be cool to do!
2. Rotating in code
AH! There we go, THAT’s better! As you can see, all three buttons are visible in portrait and landscape. BUT, what did we have to do to achieve this?
To get THIS project to work, we had to add an even hanlder in MainPage.xaml in the page tag that looks like OrientationChanged="PhoneApplicationPage_OrientationChanged" to ensure the rotation is captured. we also had to add the following code to actually do the heavy lifting for us (heavy lifting being the actual changing of the layout controls Orientation).
3.Can’t we do more in XAML instead?
Yes, we can! But to get there, we have to make one pit-stop in OrientationStates-ville. The idea here is, we want to tell WP what the UI/Page/XAML is going to look like when we get to the portrait or landscape state. In order words, when you’re in portrait, make the StackPanel vertical, when in landscape, make it horizontal. I know, I know, this is a bit of a cooked-up example, but the idea of changing the right properties still holds if you have one control property to change (ie. StackPanel.Orientation), or a bunch of other controls, like changing Grid.Row and/or Grid.Column entries. Oh and the other piece we need here, is the C# to use/set the new orientation. Remember this is a step towards complete XAML, we still have a bit of C# code yet.
If you want to cut to the chase, here’s the XAML piece.
hhhhmmmmm you REALLY want to type THAT out? NAAAAAAA Didn’t think so! Ok, so then why am I showing you THAT then? To help you appreciate what we’re going to do in Blend and that learning Blend is a necessary evil you will have to endure (if you haven’t already started endouring it). I don’t need to show a screen cap of the UI, cause, well, it hasn’t changed from the 2nd project. Hopefully you’ve moved onto Blend for this type of stuff, and if you haven’t…THIS is as good a time as any cause if you look at the XML above….it’s nasty look’n.
Ok, so let’s fire up Blend…If you don’t already have a shortcut setup, you might want to set one up now. I have mine setup to be CTRL+SHIFT+ALT+E. The “Three-Finger-Salute” helps me memorize my shortcuts and “E”…well it’s for the “E” in Expression Blend.
Once in Blend, lets make sure we’re both on the same page…..uh……..page orientation, for the emulator I mean. Let’s make sure we’re both in portrait mode. Click the Device tab on the left, then change/make sure you have Orientation set to Portrait.
Next, you will need to find the States tab on the top left, click on the little Add state group button. Rename the default VisualStateGroup to OrientationStates, this is where we are going to add both the states we need and then how we want things to look in those states.
While we’re here, let’s turn on the nice preview feature Blend will help us see what we’re doing when we click on the different states we’re going to setup.
To help make things look nice, click the little wave button to turn on FluidLayout and add 1 to the 0s Duration transition textbox.
Click Add State button beneath the previous add state button (just above the 1s you just added), add two states and rename them to Portrait and Landscape. If you notice the red circle on the right, that’s OK, we’ll get to that next.
Now comes the meat, we need to tell Blend how we want our Page/Controls to look like in the different states we just setup. This is where the “recording” metaphor you just saw, the red light. Portrait is easy, it’s already setup the way we want it, namely the StackPanel.Orientation = Vertical. For Landscape, we need to stop the recording by clicking Base on the top left, then in the Device tab, change the orientation to Landscape.
After changing the orientation, click back to States and select the Landscape state, notice how the recording starts?! Cool! OK, now we can setup our Page/Controls how we want them to look like in Landscape mode. For our cooked up example, it’s rather easy, select the StackPanel and change the orientation to Horizontal.
Yes, you have to do some “coast to coast” mouse travels to go from one side of Blend to the other. But that’s ok. Once you change the orientation, you’ll see the StackPanel reorientate horizontally, then click the Red recording again to stop it.
At this point, if you’ve followed along nicely, and you’re like me, you’ll probably F5 this now and realize……….DOH!…………it’s aint’ working Peter!!!!!! Yup! We’re missing two small pieces. First we need to add code to select one of those new Portrait or Landscape states we just setup, and lastly a change to XAML to fire that code.
First, add in the XAML to fire the OrientationChanged event.
Then add in the code that’s fired and actually selects the right state. As you can see from the code below, it manually changes the state to the name you entered above.
You can F6 (Compile) and if it’s all good, F5 to run. To simulate rotating the phone, move your mouse over the phone’s buttons, and you’ll see another overlay pop up, there are the rotate buttons there. Click them and watch how your StackPanel will now rotate and display all the buttons and text correctly.
Do you notice how the transitions are fluid? That’s the “Fluid” button we clicked on above. Try turning it off and rerun. I think you’ll like having it on (and playing/tweaking some of the options). Just go subtle with the values ok? Wickedly dramatic settings juuuuust might tick off your users. But then again, mabye you’re making a Leafs app, in which case, GO FOR IT! haha (My Habs slant showing a little? haha)
4. Look Ma, NO CODE!
Ok, thanks for the detour, but we’re now lost! Let’s get back to the highway! Starting from our previous sample, let’s work on getting rid of the C# code we just added to do the rotation and some how shoehorn it into XAML! How are we going to do it? hhhmm We’re going to do it all in Blend, hopefully you’re getting familiar with Blend now?! But before we get too deep in to Blend, let’s remove the code and XAML we JUST added. Your code should only have code for the button click (I know, I know, we COULD rip that out with MVVM Commands, I know, but we’re focusing on orientation at the moment).
What we want to do, at a very high level is add some triggers and conditional behaviours that goto a specific state (which we’ve already setup). Don’t worry if you don’t get these terms yet, it’s just the preview (you know, standard english essay writing, say what you’re going to say, say it, tell’em what you said, this is the first part LOL).
So now, let’s fire up Blend and load up the right page (ya, I have to explicitly say that cause with four projects in this one solution, I’ve already “played” with the wrong file a few times, DOH!). Also make sure you’re rotated portrait.
Click the Assets tab on the top left, then in the textbox below, start tying out the GoToStateAction in that find box. Sooner or later, you’ll see the GoToSateAction come upon the right side. Click’n’drag that down to the LayoutRoot element. Aaaaaaaaaaaaaand drag’n’drop another one, yup, you’ll need two in there.
Next, we want to start tweaking the conditions for WHEN this action is fired for each of the two we just added. Select the first/top GoToStateAction you put in there, look over on the far right, over at the Properties tab and change the Name to Portrait.
Oddly enough, Blend wants to postfix YOUR name with an integer number. Don’t worry about that (I tried, I couldn’t figure out how to change this) just go with it for now.
Next, expand the Conditions section below the Name you just set. We want to add a condition to these properties for the Portrait Action, so now click the Plus sign.
Next, we need to setup the condition. First, click the little clear square to the right of the first Value drop…..ah, just look at the pic below, easier if you see it. You see it? THAT’s the advanced options in Blend, click that, then select the DataBinding. We’re going to set the condition of this Action to the page orientation.
Next, you’ll see the Create Data Binding dialog popup. hhmm ok, Simple eh? It’s about to get complicated quickly, but stick close by!
Click the Element Property tab, the middle one and make sure the phoneApplicationPage is selected on the left hand side, on the Properties side, on the right, scroll down until you can see and select the Orientation : (PageOrientation) option then click OK.
Ok, uh, hhmmmmm Portrait? Huh? What? Didn’t you do what I told you? Didn’t you select the Orientation option? You didn’t listen did you? Ok, ok, don’t worry, EVERYTHING’s ok, it’s AAAAAAAAAAAAAAALL good! You see how it’s in yellow? The border and that clear rectangle is now yellow? The yellow is telling you that property is Data Bound, AND that value is what it is right now (well, at least what it WAS when you selected it when you setup the data binding).
Now, this sets up the left hand side of an “if/conditional” statement, we need to add the other, right hand side, we have to tell Blend WHAT this value needs to be compared to. In our case, we want to fire THIS specific ation when the Orientation value is equal to “PortriatUp”. Double check the MSDN PageOrientation Enumeration for the EXACT value to use (PortraitUp in our case).
Next we need to tell Blend WHAT to do WHEN this condition is true. Go down a bit to the Common Properties, find the StateName, hit the dropdown and select the Portrait option. This is being read from your VisualStates you added before (although this LOOKS like it’s magic/constant terms in the listbox, these are YOUR state names).
See, we can change it in XAML, and it gets reflected in that dropdown.
When you’re done with the first Portrait1 Action, it should look something like this.
Next, you’ll need to do the SAME thing for the other Action, this time call it Landscape (which gets suffixed with the “1” which we won’t fight with LOL), open up the Conditions, (this is different) add TWO conditions. PortaitUp is a magic orientation, even if you turn the phone the other way around, it’ll still be PortraitUp, but there are TWO landscapes, LandscapeLeft and LandscapeRight, you’ll need to add both of these conditions, AND make sure you change the Match dropdown to say any.
Now, don’t forget to change the StateName to change this to when this set of conditions is met, make it Lanscape OrientationState.
Ok, now that we’ve done the setup of WHEN these actions are going to be fired (as well as what they’ll do when they are fired), we need to one last thing…..FIRE THEM! Ya, we’ve done all this work but haven’t actually tied these things to anything. That’s what we’ll do next.
We want to hook up when the user rotates the phone, when the Orientation changes, we want our actions to fire/run. Make sure you’re still on the Lanscape1 Behaviour (that’s the Asset you added to the left hand side, but make sure you’re on Landscape), look over on the far right for the Trigger options and specifically the SourceObject property, click the Advanced Options little square option and then select Data Binding.
In DataBinding, simple select the Element Property Tab, then click the phoneApplicationPage and then OK.
If you did this all correctly, click the EventName and you’ll be able to select the OrientationChanged event.
NOTE: For some reason, I always seem to click the SourceName, DOH! You’ll know you clicked the wrong option when you try this next step, nothing will show up!
Replicate this for the Portrait GotoActionState, which is actually a Behaviour.
Save (CTRL+S), go back to VS, have VS reload the solution, F6 to compile, should work cause there’s hardly and C# code, then F5 to Run. You should be able to rotate the phone emulator (or the actual device) and see your page change orientation. If you don’t, then go through and make sure the settings above, for which you thought you set, actually STUCK! (while writing this, one of mine didn’t, and I had to reset it, Save, F5).
PHEW! WOW! That was long, BUT there was a lot of screen caps (I wanted to make sure you were clicking where I was clicking and not having any ambiguities, I hope it worked?). Next time, you should be able to whip through it quite quickly! First we added two behaviours, we setup their associated conditions and the State they were to change to, then we setup the associated SourceObject data binding to bind to the changing Page Orientation event. COOL!
Now that you know how to setup page rotations without any code, it’s time to grab a coffee and get coding!
MSDN: How to: Handle Orientation Changes on Windows Phone
BuildMobile: Orientation and Behaviours in WP7 by Nick Randolph
MSDN: PageOrientation Enumeration
2 comment(s) so far...
By Mani on
Wednesday, May 02, 2012 6:17 AM
Re: How do you rotate your WP7 pages/change orientation?
Kindly update the source code link.. thanks for the tutorial.
By Peter Henry on
Wednesday, May 02, 2012 8:32 AM
Re: How do you rotate your WP7 pages/change orientation?
Hi Mani, thanks for the heads up! The updated link is here. I started using the MS Live blog writer tool, and I guess it mangles the URLs a bit? I have to look into that tonight, but until then, there's the SVN code url, or you can grag file by file if you're using a browser.
Thanks for leaving a comment to finger flick me! haha Have a good week! (...and PS let me know if you release an app, I want to check it out! haha)