Click here to Skip to main content
15,885,244 members
Articles / Mobile Apps / Windows Mobile

Design Metro App using windows 8 and Visual studio 2011

Rate me:
Please Sign up or sign in to vote.
4.56/5 (5 votes)
1 May 2012CPOL3 min read 55.8K   1.8K   19   15
Design Metro App using windows 8 and Visual studio 2011

Introduction

This article is meant for .net developer who are using windows 8 and Visual studio 2011 for developing metro style app. In this article ,I will explain brief information about the metro app and demonstrate the Sample metro app design. 

What is Metro Apps  

Metro style apps are full screen apps tailored to your users' needs, tailored to the device they run on, tailored for touch interaction, and tailored to the Windows user interface. Windows helps you interact with your users, and your users interact with your app." from MSDN.

All about developing for Windows 8: http://www.buildwindows.com/

When developing Metro apps you can chose from a variety of languages and technologies:

  • HTML + JS + CSS 
  • XAML + (C# or VB)
  • XAML + (C++ or C)  

Prerequisites

About My Sample FaceBook PhotoAlbum Metro App 

  • This Sample Metro app have three screens ,first one 'Facebook Login' screen and next 'Album' screen and last one is 'Photo' screen 
  • As i like  XMAL and C# hence i am developing this sample metro application in XMAL and C# . 
  • I am using the FaceBook C# SDK to get albums and photos from FaceBook.   

Step 1   :Create Project  

With the new VS 2011 Developer tool, you will be able to create Windows Metro Style App in C# ,XMAL , Javacsript ,VB . Here i am using C# Grid Template for designing sample FaceBook Photo Album metro style app.

Image 1

Step 2   Add Client Internet Capabilities

 As My Metro App fetch the data from FaceBook hence App need's client internet connection to fetch data from facebook.

To enable to internet capabilities in metro app , double click on Package.appxmanifest file and under the Capabilities tab ,mark internet(client) as checked.  

Image 2 


Step 3:  Add login page  

This page is used to display facebook login dialogue box and authenticate the face book user. 

Image 3 

 LoginPage.xaml page have Login() method  which is used to display the Facebook login dialogue box ,authenticate the Facebook user  and fetch the albums ,photos from Facebook. 

 Below code display the FaceBook Login box

C++
//Facebook AppId
                string faceBookAppId = "285516851528865";
                //Facebook Extended Permissions
                string[] extendedPermissions = new[] { "user_about_me", "offline_access", "user_photos", "publish_stream", "friends_photos" };
                string redirectUri = "https://www.facebook.com/connect/login_success.html";
                System.Uri EndUri = new Uri(redirectUri);
                var oauth = new FacebookClient { AppId = faceBookAppId };
                var parameters = new Dictionary<string, object>
                        {
                            {"client_id",faceBookAppId},
                            { "response_type", "token" },
                            { "display", "popup" },
                            {"redirect_uri",redirectUri}
                        };

                if (extendedPermissions != null && extendedPermissions.Length > 0)
                {
                    var scope = new StringBuilder();
                    scope.Append(string.Join(",", extendedPermissions));
                    parameters["scope"] = scope.ToString();
                }

                Uri loginUrl = oauth.GetLoginUrl(parameters);
                //Show facebook login Dialogue box
                WebAuthenticationResult WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
                                                         WebAuthenticationOptions.None,
                                                         loginUrl, EndUri
                                                         );
Below code shows that once FaceBook authentication is successful ,it will navigate to Album screen (GroupedItemsPage.xaml)
C++
//Show Albums if Facebook login successfull
if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
{
    FacebookOAuthResult fbAuthResult = oauth.ParseOAuthCallbackUrl(new Uri(WebAuthenticationResult.ResponseData.ToString()));
    var fbClient = new FacebookClient(fbAuthResult.AccessToken);
    //Get Facebook Albums
    dynamic fbAlbums = await fbClient.GetTaskAsync("/me/albums");
    DataSource dataSource = new DataSource();
    foreach (var a in fbAlbums.data)
    {
        //Get Facebook Photos
       var fbPhotos = await fbClient.GetTaskAsync(a.id + "/photos");
       string albumPath="";
       foreach (var p in fbPhotos.data)
       {
           albumPath = p.source;
           break;
       }

       var album = new Album(a.name, albumPath);
       foreach (var p in fbPhotos.data)
           album.Photos.Add(new Photo("", p.source, album));

       dataSource.Albums.Add(album);
    }

    Frame.Navigate(typeof(GroupedphotosPage), dataSource.Albums);

Step4 : Customize the GroupedItemsPage.xaml and ItemDetailPage.xaml file to display Albums and Photos 

  • GroupedItemsPage.xaml page is used to display Facebook user Albums.
  • ItemDetailPage.xaml page is used to display Facebook user album photos.
GroupedItemsPage.xaml  

Preview of Album screen  

Image 4

 

When 'GroupEdItemPage' page loads store the passed data into DataViewModel["Albums"] , we will use this value in design page to display the User Album's 

C#
/// <summary>
       /// Invoked when this page is about to be displayed in a Frame.
       /// </summary>
       /// <param name="e">Event data that describes how this page was reached.  The Parameter
       /// property provides the grouped collection of photos to be displayed.</param>
       protected override void OnNavigatedTo(NavigationEventArgs e)
       {
           this.DefaultViewModel["Albums"] = e.Parameter;
       } 

Creating the UserControl ResourcesResources for Album collection , we will use this resource in GridView to display the Albums.  

C++
<UserControl.Resources>

       <!-- Collection of grouped photos displayed by this page -->
       <CollectionViewSource
           x:Name="groupedphotosViewSource"
           Source="{Binding Albums}"
           IsSourceGrouped="False"
           ItemsPath="Photos"
           d:Source="{Binding Albums, Source={d:DesignInstance Type=data:DataSource, IsDesignTimeCreatable=True}}"/>
   </UserControl.Resources> 

Displaying the Albums in Gridview   

C++
<GridView
                x:Name="itemGridView"
                AutomationProperties.AutomationId="ItemGridView"
                AutomationProperties.Name="Face Book Photo Album"
                Margin="116,0,40,46"
                ItemsSource="{Binding Source={StaticResource groupedphotosViewSource}}"
                ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
                SelectionMode="None"
                IsItemClickEnabled="True"
                ItemClick="ItemView_ItemClick">
                
                  <GridView.ItemsPanel>
                    <ItemsPanelTemplate>                        
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.GroupStyle>
                    <GroupStyle>

                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>

When user click on Album , following method invoked which navigates to Photo screen.

C#
/// <summary>
        /// Invoked when an item within a group is clicked.
        /// </summary>
        /// <param name="sender">The GridView (or ListView when the application is snapped)
        /// displaying the item clicked.</param>
        /// <param name="e">Event data that describes the item clicked.</param>
        void ItemView_ItemClick(object sender, ItemClickEventArgs e)
        {
            // Navigate to the appropriate destination page, configuring the new page
            // by passing required information as a navigation parameter
            
            this.Frame.Navigate(typeof(ItemDetailPage), e.ClickedItem);
        }  

ItemDetailPage.xaml 

 Preview of photo screen

Image 5 

When 'ItemDetailPage' page loads store the  Selected Album and Photos object into the DefaultViewModel , we will use these object to display the photos on screen 

C#
/// <summary>
       /// Invoked when this page is about to be displayed in a Frame.
       /// </summary>
       /// <param name="e">Event data that describes how this page was reached.  The Parameter
       /// property provides the initial item to be displayed.</param>
       protected override void OnNavigatedTo(NavigationEventArgs e)
       {
           var album = (Album)e.Parameter;
           this.DefaultViewModel["Album"] = album;
           this.DefaultViewModel["Photos"] = album.Photos ;
           //this.flipView.SelectedItem = item;

Creating static resource for photo, we will use this resource in FilpView to display the Photos 

C#
<UserControl.Resources>

        <!-- Collection of items displayed by this page -->
        <CollectionViewSource
            x:Name="itemsViewSource"
            Source="{Binding Photos}"
            d:Source="{Binding Album[0].Photos, Source={d:DesignInstance Type=data:DataSource, IsDesignTimeCreatable=True}}"/>
    </UserControl.Resources>

Displaying the Photos in FilpView 

C#
<FlipView
           x:Name="flipView"
           AutomationProperties.AutomationId="ItemsFlipView"
           AutomationProperties.Name="Item Details"
           Grid.Row="1"
           Margin="0,-3,0,0"
           ItemsSource="{Binding Source={StaticResource itemsViewSource}}">

           <FlipView.ItemTemplate>
               <DataTemplate>

                   <!--
                       UserControl chosen as the templated item because it supports visual state management
                       Loaded/unloaded events explicitly subscribe to view state updates from the page
                   -->
                   <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
                       <ScrollViewer x:Name="scrollViewer" Style="{StaticResource HorizontalScrollViewerStyle}" Grid.Row="1">

                           <!-- Content is allowed to flow across as many columns as needed -->
                           <common:RichTextColumns x:Name="richTextColumns" Margin="117,0,117,47">
                               <RichTextBlock x:Name="richTextBlock" Width="560" Style="{StaticResource ItemRichTextStyle}">

                                   <Paragraph LineStackingStrategy="MaxHeight">
                                       <InlineUIContainer>
                                           <Image x:Name="image" MaxHeight="480" Margin="0,20,0,10" Stretch="Uniform" Source="{Binding Image}"/>
                                       </InlineUIContainer>
                                   </Paragraph>

                               </RichTextBlock>

                               <!-- Additional columns are created from this template -->
                               <common:RichTextColumns.ColumnTemplate>
                                   <DataTemplate>
                                       <RichTextBlockOverflow Width="560" Margin="80,0,0,0">
                                           <RichTextBlockOverflow.RenderTransform>
                                               <TranslateTransform X="-1" Y="4"/>
                                           </RichTextBlockOverflow.RenderTransform>
                                       </RichTextBlockOverflow>
                                   </DataTemplate>
                               </common:RichTextColumns.ColumnTemplate>
                           </common:RichTextColumns>

                           <VisualStateManager.VisualStateGroups>

                               <!-- Visual states reflect the application's view state inside the FlipView -->
                               <VisualStateGroup>
                                   <VisualState x:Name="FullScreenLandscape"/>
                                   <VisualState x:Name="Filled"/>

                                   <!-- Respect the narrower 100-pixel margin convention for portrait -->
                                   <VisualState x:Name="FullScreenPortrait">
                                       <Storyboard>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextColumns" Storyboard.TargetProperty="Margin">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="97,0,87,57"/>
                                           </ObjectAnimationUsingKeyFrames>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="image" Storyboard.TargetProperty="MaxHeight">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="400"/>
                                           </ObjectAnimationUsingKeyFrames>
                                       </Storyboard>
                                   </VisualState>

                                   <!-- When snapped, the content is reformatted and scrolls vertically -->
                                   <VisualState x:Name="Snapped">
                                       <Storyboard>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextColumns" Storyboard.TargetProperty="Margin">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="17,0,17,57"/>
                                           </ObjectAnimationUsingKeyFrames>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="scrollViewer" Storyboard.TargetProperty="Style">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource VerticalScrollViewerStyle}"/>
                                           </ObjectAnimationUsingKeyFrames>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextBlock" Storyboard.TargetProperty="Width">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="280"/>
                                           </ObjectAnimationUsingKeyFrames>
                                           <ObjectAnimationUsingKeyFrames Storyboard.TargetName="image" Storyboard.TargetProperty="MaxHeight">
                                               <DiscreteObjectKeyFrame KeyTime="0" Value="160"/>
                                           </ObjectAnimationUsingKeyFrames>
                                       </Storyboard>
                                   </VisualState>
                               </VisualStateGroup>
                           </VisualStateManager.VisualStateGroups>
                       </ScrollViewer>
                   </UserControl>
               </DataTemplate>
           </FlipView.ItemTemplate>
       </FlipView> 

Step5: Set LoginPage.xmal page as startup page 

Open the App.xmal.cs and set the LoginPage As startup paage,  as shown below  

C++
protected override void OnLaunched(LaunchActivatedEventArgs args)
      {
          // TODO: Create a data model appropriate for your problem domain to replace the sample data
          var sampleData = new DataSource();

          if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
          {
              //TODO: Load state from previously suspended application
          }

          // Create a Frame to act navigation context and navigate to the first page,
          // configuring the new page by passing required information as a navigation
          // parameter
          var rootFrame = new Frame();
          rootFrame.Navigate(typeof(LoginPage));

          // Place the frame in the current Window and ensure that it is active
          Window.Current.Content = rootFrame;
          Window.Current.Activate();
      } 

Attached Code  

SampleFaceBookPhoto.zip contain the all the my SampleFacebookPhotoalbumm Metro App files.

History

Keep a running update of any changes or improvements you've made here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United States United States
Working on Microsoft Technologies and Cloud computing.

Comments and Discussions

 
QuestionBuild failed. Not able to run application Pin
Sumit_Sood30-Nov-12 0:43
Sumit_Sood30-Nov-12 0:43 
QuestionConnect to faceboo without UI Pin
Assaf Dar30-Jul-12 5:49
Assaf Dar30-Jul-12 5:49 
AnswerRe: Connect to faceboo without UI Pin
Umesh Khandelwal30-Jul-12 5:55
professionalUmesh Khandelwal30-Jul-12 5:55 
GeneralRe: Connect to faceboo without UI Pin
Assaf Dar8-Aug-12 4:24
Assaf Dar8-Aug-12 4:24 
GeneralRe: Connect to faceboo without UI Pin
Timheit28-Jan-13 5:05
Timheit28-Jan-13 5:05 
QuestionException with vs2012 Pin
Assaf Dar27-Jul-12 0:32
Assaf Dar27-Jul-12 0:32 
QuestionCan you help me on Windows 8 Metro App Pin
Dwarapudi19-Jul-12 2:49
Dwarapudi19-Jul-12 2:49 
AnswerRe: Can you help me on Windows 8 Metro App Pin
Umesh Khandelwal20-Jul-12 20:27
professionalUmesh Khandelwal20-Jul-12 20:27 
QuestionGetting Error during running the sample code in windows 8 in VS 2012 Pin
kishorekumarmandal12-Jul-12 2:45
kishorekumarmandal12-Jul-12 2:45 
AnswerRe: Getting Error during running the sample code in windows 8 in VS 2012 Pin
Umesh Khandelwal20-Jul-12 20:26
professionalUmesh Khandelwal20-Jul-12 20:26 
QuestionI can't mak eit run in windows 8 vs 2012 Pin
Member 918209627-Jun-12 21:52
Member 918209627-Jun-12 21:52 
AnswerRe: I can't mak eit run in windows 8 vs 2012 Pin
Umesh Khandelwal10-Jul-12 2:36
professionalUmesh Khandelwal10-Jul-12 2:36 
GeneralMy vote of 5 Pin
Mohammad A Rahman22-May-12 17:53
Mohammad A Rahman22-May-12 17:53 
GeneralCool!!! Pin
Moch Lutfi10-May-12 15:46
Moch Lutfi10-May-12 15:46 
GeneralMy vote of 4 Pin
Prafulla Hunde1-May-12 6:27
Prafulla Hunde1-May-12 6:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.