Click here to Skip to main content
Click here to Skip to main content

Design Metro App using windows 8 and Visual studio 2011

, 1 May 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
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.

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.  

 


Step 3:  Add login page  

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

 

 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

//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)
                //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  

 

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 

 /// <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.  

 <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   

<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.

/// <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

 

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 

 /// <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 

<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 

 <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  

  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)

Share

About the Author

Umesh Khandelwal
Wipro
India India
Working in Microsoft Technologies.

Comments and Discussions

 
QuestionBuild failed. Not able to run application PinmemberSumit_Sood30-Nov-12 1:43 
QuestionConnect to faceboo without UI PinmemberAssaf Dar30-Jul-12 6:49 
AnswerRe: Connect to faceboo without UI PinmemberUmesh Khandelwal30-Jul-12 6:55 
GeneralRe: Connect to faceboo without UI PinmemberAssaf Dar8-Aug-12 5:24 
GeneralRe: Connect to faceboo without UI PinmemberTimheit28-Jan-13 6:05 
QuestionException with vs2012 PinmemberAssaf Dar27-Jul-12 1:32 
QuestionCan you help me on Windows 8 Metro App PinmemberDwarapudi19-Jul-12 3:49 
AnswerRe: Can you help me on Windows 8 Metro App PinmemberUmesh Khandelwal20-Jul-12 21:27 
QuestionGetting Error during running the sample code in windows 8 in VS 2012 Pinmemberkishorekumarmandal12-Jul-12 3:45 
AnswerRe: Getting Error during running the sample code in windows 8 in VS 2012 PinmemberUmesh Khandelwal20-Jul-12 21:26 
QuestionI can't mak eit run in windows 8 vs 2012 PinmemberMember 918209627-Jun-12 22:52 
AnswerRe: I can't mak eit run in windows 8 vs 2012 PinmemberUmesh Khandelwal10-Jul-12 3:36 
GeneralMy vote of 5 PinmemberMohammad A Rahman22-May-12 18:53 
GeneralCool!!! Pinmemberh4ckm03d10-May-12 16:46 
GeneralMy vote of 4 PinmemberPrafulla Hunde1-May-12 7:27 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 1 May 2012
Article Copyright 2012 by Umesh Khandelwal
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid