This is a "Blitz Code" post. It should take 10 minutes for you to read through. The goal is to get started quickly, so we will only skim through the concepts. The post is primarily geared towards introducing WP7 to new developers.

The WP7 UI chrome consists of PhoneApplicationFrame and one or more PhoneApplicationPage. Each application will have a single frame and can have multiple pages. Frames and pages concept is similar to the SL 3.0. We will touch upon few concepts related to designing a page, plugging in your custom styles and using an ApplicationBar in your project.

Choosing a page layout

In the new project template, the start page of the app is Mainpage.xml. The page design is specified by XAML (a markup language). For a page, you will have three major options to specify a layout - Grid, StackPanel and Canvas. Let's briefly look at each of these.

Hello Grid!

Our objective here is: divide the available UI space into a MxN grid. Each rectangle so obtained can contain an UI element or another UI container/grid. Using a grid layout consists of two simple steps:

  1. Define the grid columns and rows
    Do this using the RowDefinition(s) and ColumnDefinition(s).
  2. Fill in the content
    For each element, specify the Grid.Row and Grid.Column to fit in.

That's pretty simple. Let's create a 2x2 grid and see how the XAML looks like. Here's the related code I used:

image <Grid x:Name="LayoutRoot" ShowGridLines="True" Background="{StaticResource PhoneBackgroundBrush}"> 
  <Grid.RowDefinitions> 
    <RowDefinition Height="Auto"/> 
    <RowDefinition Height="*"/> 
  </Grid.RowDefinitions> 
  <!--TitleGrid is the name of the application and page title--> 
  <Grid x:Name="TitleGrid" Grid.Row="0"> 
    <TextBlock Text="MY APPLICATION" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/> 
    <TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/> 
  </Grid> 

  <!--ContentGrid is empty. Place new content here--> 
  <Grid x:Name="ContentGrid" ShowGridLines="True" Grid.Row="1"> 
    <Grid.RowDefinitions> 
      <RowDefinition Height="100" /> 
      <!-- * means fill up all left over space --> 
      <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

    <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="100" /> 
      <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 

    <Grid Grid.Column="0" Grid.Row="0"> 
      <Button Content="0,0"></Button> 
    </Grid> 

    <Grid Grid.Row="1" Grid.Column="1"> 
      <Button Content="A Button in 1,1"></Button> 
    </Grid> 
  </Grid> 
</Grid>


To arrange items further, you can use the VerticalAlignment and HorizontalAlignment property. It takes four values, Bottom/Center/Top are self explanatory. Stretch will cover up all available area.

The StackPanel

Here the UI elements are arranged one on top of another. You can customize the height/width and other properties for each of the elements. Usually I use this layout for real quick mock ups (and test out the backend code changes). Here is the code:

image <Grid x:Name="LayoutRoot" ShowGridLines="True" Background="{StaticResource PhoneBackgroundBrush}"> 
  <Grid.RowDefinitions> 
    <RowDefinition Height="Auto"/> 
    <RowDefinition Height="*"/> 
  </Grid.RowDefinitions> 
  <!--TitleGrid is the name of the application and page title--> 
  <Grid x:Name="TitleGrid" Grid.Row="0"> 
    <TextBlock Text="MY APPLICATION" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/> 
    <TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/> 
  </Grid> 

  <!--ContentGrid is empty. Place new content here--> 
  <Grid x:Name="ContentGrid" ShowGridLines="True" Grid.Row="1"> 
    <StackPanel Orientation="Horizontal"> 
      <Button Content="foo"></Button> 
      <Button Content="bar" Width="100"></Button> 
      <Button Content="zar" Width="200"></Button> 
    </StackPanel> 
  </Grid> 
</Grid>

Orientation is a key property of a StackPanel. Use it to specify how your UI elements stack up - horinzontally or vertically.

Compared to above two, the Canvas layout is not quite flexible. You'd need to specify the coordinates for an UI element to position it. Since UI positions for the child elements are absolute, changes in form factor may make UI unusable.

Styling the elements

Similar to CSS for web apps, you can define your own Style Resources and use them through out the application. The default project template comes with a set of predefined styles you can use. Take a look at the App.xaml file. It is often a good practice to define your own set of resources/templates. This allows reusability and keeps the look and feel of your application consistent.

I linked the UI element's Style property to a StaticResource. I created a custom resource, call it MyStyle. The TargetType attribute ensures that only the target UI element can use the style. The code snippet is given below.

image <Grid x:Name="LayoutRoot" ShowGridLines="True" Background="{StaticResource PhoneBackgroundBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitleGrid is the name of the application and page title-->
    <Grid x:Name="TitleGrid" Grid.Row="0">
        <TextBlock Text="MY APPLICATION" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/>
        <TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/>
    </Grid>

    <!--ContentGrid is empty. Place new content here-->
    <Grid x:Name="ContentGrid" ShowGridLines="True" Grid.Row="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0" Orientation="Vertical">
            <Button Height="300">
                <Button.Content>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Margin="10" Style="{StaticResource PhoneTextAccentStyle}">
                            Foo and Bar
                        </TextBlock>
                        <Rectangle Height="100" Fill="White" />
                        <ToggleButton Content="Toggle Me" />
                    </StackPanel>
                </Button.Content>
            </Button>
        </StackPanel>

        <Button Grid.Row="1" Content="Grid Position: 1,0" Style="{StaticResource MyStyle}">
        </Button>
    </Grid>
</Grid>

<!-- STYLE for Button: MyStyle. Put this snippet in App.xaml file -->
<Style x:Key="MyStyle" TargetType="Button">
    <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeLarge}"/>
    <Setter Property="Background" Value="White"/>
    <Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
</Style>

 

Application bar

The ApplicationBar control provides a nice way to hook up a menu bar and icon buttons to your application. It's pretty easy:

  • Add reference to Microsoft.Phone.Shell in your project.
  • Copy/paste the code below :)

To create the images for my application, I used 48x48 PNG (transparent background). The actual text in the icon is 26x26 (White foreground).

clip_image001[4]clip_image002[4] <Grid x:Name="LayoutRoot" ShowGridLines="True" Background="{StaticResource PhoneBackgroundBrush}"> 
  <Grid.RowDefinitions> 
    <RowDefinition Height="Auto"/> 
    <RowDefinition Height="*"/> 
  </Grid.RowDefinitions> 

  <!--TitleGrid is the name of the application and page title--> 
  <Grid x:Name="TitleGrid" Grid.Row="0"> 
    <TextBlock Text="MY APPLICATION" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/> 
    <TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/> 
  </Grid> 

  <!--ContentGrid is empty. Place new content here--> 
  <Grid x:Name="ContentGrid" ShowGridLines="True" Grid.Row="1"> 
    <Button Content="Foo" Background="DarkGray" Height="100"></Button> 
    <Button Content="Bar" VerticalAlignment="Bottom"></Button> 
  </Grid> 
</Grid> 

<phoneNavigation:PhoneApplicationPage.ApplicationBar> 
  <shell:ApplicationBar Visible="True" IsMenuEnabled="True"> 
    <shell:ApplicationBar.Buttons> 
      <shell:ApplicationBarIconButton IconUri="/button1.png"></shell:ApplicationBarIconButton> 
      <shell:ApplicationBarIconButton IconUri="/button2.png"></shell:ApplicationBarIconButton> 
      <shell:ApplicationBarIconButton IconUri="/button3.png"></shell:ApplicationBarIconButton> 
    </shell:ApplicationBar.Buttons> 
    <shell:ApplicationBar.MenuItems> 
      <shell:ApplicationBarMenuItem Text="Menu1"></shell:ApplicationBarMenuItem> 
      <shell:ApplicationBarMenuItem Text="Menu2"></shell:ApplicationBarMenuItem> 
    </shell:ApplicationBar.MenuItems> 
  </shell:ApplicationBar> 
</phoneNavigation:PhoneApplicationPage.ApplicationBar> 

i1, i2 and i3 are the icons specified in above snippet (button1-3.png). Menu1 and Menu2 are the menu bar entries.

 

Where next?

So far so good. By now, I hope you already have a small app to try out the UI. Next, you may dig into the following concepts:

References

[1] Scott's post on silverlight layout management
[2] MSDN on Static resources and on Relative resources
[3] Scott's post on silverlight control templates
[4] MSDN on How to create ApplicationBar for WindowsPhone

Hope this helps.

By the way, the term "Blitz Code" comes from blitz chess (also called Lightning chess, where each player gets 5 minutes to play). Do drop me a line if you'd like to play an online blitz game sometime :)