Avtar Sohi

Tips and tricks for Powershell, XAML Asp.net, C#...

Part 1: How to create window 8 app using "Grid App (XAML)" template from scratch.

In this tutorial, you will learn the detail of “Grid App (XAML)” template and understanding of this template will help you to create your window 8 app.

Before you start…

  • You need Windows 8 or 8.1 OS
  • Microsoft Visual Studio Express 2012 for Windows 8. To download them, see Get the tools.
  • You also need a developer license. For instructions, see Get a developer license.

Abstract…

Here we will create a simple window 8 style app using C# and XAML and then we will investigate the XAML and code that Visual Studio 2012 generates when you create the solution. We will run the app and see that it uses sample data and its binding. On a high level, you will get a better understanding how the navigation within the app works and how binding is done. A deep understanding of this template will help you to design your application in a better manner plus you can decide whether this template is applicable to your window 8 app or not.

Let’s start…

  • Launch Visual Studio 2012 by typing “Vis” and selecting visual studio.

           

  • It will launch visual studio 2012.

           

  • Click File – > New – > Project

           

  • You should see the New Project dialog. Select Templates – > Visual C# and then select the Windows Store category. Select the Grid App (XAML) template.

          

  • Type MyFirstApp for the name of the app and accept the defaults for everything else. Click OK to create your new project. NOTE: In Windows 8, all software development will require a Developer License. After starting Visual Studio, you might be prompted to license your machine for Development. Click I agree when prompted. If Visual Studio asks for a Microsoft account, type in your Hotmail or live account and click OK. For more information: http://msdn.microsoft.com/en-us/library/windows/apps/hh974578.aspx

 

  • Notice that Visual Studio creates a directory structure for you:

           

    1. The Properties folder contains the some assemblyinfo and project properties.
    2. The References folder contains references to other assemblies that this project needs.
    3. The Assets folder contains default logos and SplashScreen images and you can use this folder to add custom logo too which can be used by window 8.
    4. The Common folder contains classes and XAML styles that simplify application development. You can add your converted classes to this folder and there are already two converter provided by Grid App (XAML) template. It also has BindableBase.cs class which should be used as a base class for all datamodel classes. Now you no need to implement INotifyPropertyChanged Interface for your data model since BindableBase.cs has implemented INotifyPropertyChanged Interface. You can read the ReadMe.txt in that folder for more information. Apart from common source and style this folder also include file by name “SuspensionManager.cs” file. SuspensionManager is a helper class that we use to simplify lifecycle management for the app. It handles several things for you. It saves and restores the navigation state of the Frame that hosts the app pages. Basically it serializes the page state data and writes it to an XML file in your app’s local storage.
    5. The DataModel folder contains a SampleDataSource.cs file. The code in this file generates sample data.
    6. App.xaml contains the xaml and resources for the window 8 Style app. It initializes the singleton Application object.  This is the first line of authored code executed, and as such is the logical equivalent of main() or WinMain(). It also has method which gets called while application move to suspended stage or application is launched normally by end user. You can hook your custom action in these methods if you want to perform certain action while application move to suspended or launch stage.
    7. GroupDetailPage.xaml displays a collection/Group and the items within it. Basically it enables a user to view group details on the left and items on the right, and select an item to navigate to the full-page item view and that is ItemDetailPage.xaml.
    8. GroupedItemsPage.xaml is the first page that appears when you run this app. It displays collections and the items in them. Basically it is the home page. It enables a user to view the groups and items, and either selects an item to navigate to the full-page item view, or a select a group label to navigate to the group details page.
    9. ItemDetailPage.xaml displays an individual item or full-page view for an item.

    10. Package.appxmanifest.xaml is a special file that details your application package, its capabilities, and how your app is represented to the user. This file includes several image files, like splashscreen.png for the splash screen image, and SmallLogo.png and Logo.png.

                       

  • Let’s run the application and check how it looks like with default setting. Click Build ->Build Solution to build the solution and then press F5 to run the app.
  • Now when you run your application you can see “Splash screen” which you mentioned in your Package.appmanifest file.

           

  • After some time, actual app will be loaded and when the app launches, the main page displays collections and the items in them.There are six collections and you can scroll left and right to view them all.

                     

  • Select an ItemTitle: 1 by clicking its rectangle. You will see the detail page for Item Title: 1.

                    

  • Now if you want to move to Item2 then you can move/hover the mouse on the right and you should see a button with a right arrow.  Click that to scroll to the next item in the list. On the left hand side you can click the left arrow button to scroll backwards. Similarly on touch screen device you can flick horizontally to move to next item.

                   

  • Click or touch the back button in the upper left. You will go back to the main page.

  • Now let’s go to Group Title 1 detail by clicking on “Group Title: 1” and now you will see the summary page for the Group.

                  

  • Now one thing you might ask: where is close button to close this application? ……. A window 8 style app is really a window that has no “chrome” hence we don’t’ have any close button in win 8 app. You can alt-tab back to Visual Studio. Do that now and click on the stop debugging icon. Note: Stop debugging will not close the window 8 app. To close window 8 app you have to press Alt-F4. It will close the app. When user press Alt-F4, behind the seen app goes to suspended state for 10 second and then move to terminate state.

  • What is Simulator: Visual Studio 2012 offers several options to test your window 8 app. You can run the app in a simulator or you can run the app on the local machine, as you just did. To use the simulator, select Simulator from the drop-down list associated with the Run button.

                

  • Press F5 to run the app in the Simulator. It will take some while to launch app in Simulator. Once loaded you can notice the toolbar on the right. Click some of the buttons to check the functionality. For example: some of the buttons will rotate app horizontally or vertically to simulate the experience which end user will have on touch screen device.

                

The Simulator is a Terminal Services session into the local machine. You can bring up Task Manager and select the Users tab. You will see a second session under the same login credentials start up.

                  

Return to Visual Studio and press the stop debugging icon. Notice stop debugging doesn’t close the simulator, Simulator is still open. This can be a benefit to save time as you can keep it open across multiple debugging sessions. Now next question come up: How to close the simulator since there is no close button on simulator window: Since minimizing click does not exit the simulator. You can exit it by explicitly clicking exit in the task bar. Now close the simulator. Move back to Local Machine debugging by selecting Local Machine from the dropdown list associated with the Run button.

Till now you understand the structure of the solution and different file and their importance and how to launch app in visual studio 2012. Let’s move to next part where I will explain each file of this template.

  • Let’s start with App.xaml: Open App.xaml file. Check how it includes a file “Common/StandardStyles.xaml”. This file contains styles used throughout the app. Once style file added to ResourceDictionary it is available to all files included in current solution. It’s like a global variable available to all, throughout the app.

                  

  • OpenApp.xaml.cs file. App.xaml.cs is the code-behind file for App.xaml and it is a partial calss. Together, the XAML and code-behind make a complete class. App.xaml.cs and is the entry point for your app. It contains a constructor that calls the InitializeComponent method. It’s generated by Visual Studio, and its main purpose is to initialize the elements declared in the XAML file. App.xaml.cs also contains methods to handle activation and suspension of the app. It has two methods: OnLaunched and OnSuspending. As name suggesting OnLaunched gets called when app moves to Launch state and OnSuspending gets called when app moves to Suspended state.  

               

 sealed partial class App : Application

    {

        ///<summary>

        /// Initializes the singleton Application object.  This is the first line of authored code

        /// executed, and as such is the logical equivalent of main() or WinMain().

        ///</summary>

        public App()

        {

            this.InitializeComponent();

            this.Suspending += OnSuspending;

        }

 

        ///<summary>

        /// Invoked when the application is launched normally by the end user.  Other entry points

        /// will be used when the application is launched to open a specific file, to display

        /// search results, and so forth.

        ///</summary>

        ///<param name=”args”>Details about the launch request and process.</param>

        protected override async void OnLaunched(LaunchActivatedEventArgs args)

        {

            Frame rootFrame = Window.Current.Content as Frame;

 

            // Do not repeat app initialization when the Window already has content,

            // just ensure that the window is active

 

            if (rootFrame == null)

            {

                // Create a Frame to act as the navigation context and navigate to the first page

                rootFrame = new Frame();

                //Associate the frame with a SuspensionManager key                               

                SuspensionManager.RegisterFrame(rootFrame, “AppFrame”);

 

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)

                {

                    // Restore the saved session state only when appropriate

                    try

                    {

                        await SuspensionManager.RestoreAsync();

                    }

                    catch (SuspensionManagerException)

                    {

                        //Something went wrong restoring state.

                        //Assume there is no state and continue

                    }

                }

 

                // Place the frame in the current Window

                Window.Current.Content = rootFrame;

            }

            if (rootFrame.Content == null)

            {

                // When the navigation stack isn’t restored navigate to the first page,

                // configuring the new page by passing required information as a navigation

                // parameter

                if (!rootFrame.Navigate(typeof(GroupedItemsPage), “AllGroups”))

                {

                    throw new Exception(“Failed to create initial page”);

                }

            }

            // Ensure the current window is active

            Window.Current.Activate();

        }

 

        ///<summary>

        /// Invoked when application execution is being suspended.  Application state is saved

        /// without knowing whether the application will be terminated or resumed with the contents

        /// of memory still intact.

        ///</summary>

        ///<param name=”sender”>The source of the suspend request.</param>

        ///<param name=”e”>Details about the suspend request.</param>

        private async void OnSuspending(object sender, SuspendingEventArgs e)

        {

            var deferral = e.SuspendingOperation.GetDeferral();

            await SuspensionManager.SaveAsync();

            deferral.Complete();

        }

    }

  • As we understand we have SuspensionManager Class for navigation and in order to use its functionality, we have to register the main app Frame. We register the Frame in Onlaunched method

 

 if (rootFrame == null)

            {

                // Create a Frame to act as the navigation context and navigate to the first page

                rootFrame = new Frame();

                //Associate the frame with a SuspensionManager key                               

                SuspensionManager.RegisterFrame(rootFrame, “AppFrame”);

   

  • LayoutAwarePage.cs file: As you know accelerometer is the feature used by tablets user which allow user to orient their tablets in any orientation they want. Developers have to handle these changes and in developer preview each page subscribed, in the code behind to the orientation event that gets fired but now this functionality has been moved to Layoutmanager.cs file. LayourManger class server as a base class of all code behind to provide dataViewModel functionality to them. Here are some of the methods that handle that:

  •  #region Visual state switching

     

            ///<summary>

            /// Invoked as an event handler, typically on the <see cref=”FrameworkElement.Loaded”/>

            /// event of a <see cref=”Control”/> within the page, to indicate that the sender should

            /// start receiving visual state management changes that correspond to application view

            /// state changes.

            ///</summary>

            ///<param name=”sender”>Instance of <see cref=”Control”/> that supports visual state

            /// management corresponding to view states.</param>

            ///<param name=”e”>Event data that describes how the request was made.</param>

            ///<remarks>The current view state will immediately be used to set the corresponding

            /// visual state when layout updates are requested.  A corresponding

            ///<see cref=”FrameworkElement.Unloaded”/> event handler connected to

            ///<see cref=”StopLayoutUpdates”/> is strongly encouraged.  Instances of

            ///<see cref=”LayoutAwarePage”/> automatically invoke these handlers in their Loaded and

            /// Unloaded events.</remarks>

            ///<seealso cref=”DetermineVisualState”/>

            ///<seealso cref=”InvalidateVisualState”/>

            public void StartLayoutUpdates(object sender, RoutedEventArgs e)

            {

                var control = sender as Control;

                if (control == null) return;

                if (this._layoutAwareControls == null)

                {

                    // Start listening to view state changes when there are controls interested in updates

                    Window.Current.SizeChanged += this.WindowSizeChanged;

                    this._layoutAwareControls = new List<Control>();

                }

                this._layoutAwareControls.Add(control);

     

                // Set the initial visual state of the control

                VisualStateManager.GoToState(control, DetermineVisualState(ApplicationView.Value), false);

            }

     

            private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs e)

            {

                this.InvalidateVisualState();

            }

     

            ///<summary>

            /// Invoked as an event handler, typically on the <see cref=”FrameworkElement.Unloaded”/>

            /// event of a <see cref=”Control”/>, to indicate that the sender should start receiving

            /// visual state management changes that correspond to application view state changes.

            ///</summary>

            ///<param name=”sender”>Instance of <see cref=”Control”/> that supports visual state

            /// management corresponding to view states.</param>

            ///<param name=”e”>Event data that describes how the request was made.</param>

            ///<remarks>The current view state will immediately be used to set the corresponding

            /// visual state when layout updates are requested.</remarks>

            ///<seealso cref=”StartLayoutUpdates”/>

            public void StopLayoutUpdates(object sender, RoutedEventArgs e)

            {

                var control = sender as Control;

                if (control == null || this._layoutAwareControls == null) return;

                this._layoutAwareControls.Remove(control);

                if (this._layoutAwareControls.Count == 0)

                {

                    // Stop listening to view state changes when no controls are interested in updates

                    this._layoutAwareControls = null;

                    Window.Current.SizeChanged -= this.WindowSizeChanged;

                }

            }

And apart from these handlers there is a DefaultViewModel property in the LayoutAwarePage class. This property will be used to bind data to xaml control. You can check code behind of GroupedItemPage.xaml.cs.

  •  ///<summary>

            /// An implementation of <see cref=”IObservableMap&lt;String, Object&gt;”/> designed to be

            /// used as a trivial view model.

            ///</summary>

            protected IObservableMap<String, Object> DefaultViewModel

            {

                get

                {

                    return this.GetValue(DefaultViewModelProperty) as IObservableMap<String, Object>;

                }

     

                set

                {

                    this.SetValue(DefaultViewModelProperty, value);

                }

            }

  

  • GroupedItemsPage.xaml.cs: Open this page and you can see the collection of sample data group is added to the DefaultViewModel property bag.

  •  protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

            {

                // TODO: Create an appropriate data model for your problem domain to replace the sample data

                var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);

                this.DefaultViewModel[“Groups”] = sampleDataGroups;        }                     

  • Now go to GroupedItemsPage.xaml, you can see at the top inside Page.Resources tag, that it uses this “Groups” as the Source of the CollectionViewSource. The name of this source is groupedItemsViewSource

   <CollectionViewSource
                x:Name=”groupedItemsViewSource”
                Source=”{Binding Groups}”
                IsSourceGrouped=”true”
                ItemsPath=”TopItems”
                d:Source=”{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}”/>

This page uses a GridView to display the collections and items. You can see the groupedItemsViewSource refer here which is bind to the ItemsSource property of GridView.

        

Inside GroupedItemsPage.xaml.cs file, when the user clicks an individual item, the code uses the Navigate method on the Frame again to go to the ItemDetailPage 

  •   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

                var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;

                this.Frame.Navigate(typeof(ItemDetailPage), itemId);

            }

In that same GroupedItemsPage.xaml.cs file, when the user clicks a Group header, the code uses the Navigate method on the Frame to go to the GroupDetailPage                     

  • void Header_Click(object sender, RoutedEventArgs e)

            {

                // Determine what group the Button instance represents

                var group = (sender as FrameworkElement).DataContext;

     

                // Navigate to the appropriate destination page, configuring the new page

                // by passing required information as a navigation parameter

                this.Frame.Navigate(typeof(GroupDetailPage), ((SampleDataGroup)group).UniqueId);

            }

  • Open the ItemDetailPage.xaml file. This page uses a FlipView to enable scrolling back and forth through the items in a collection.

                   

  • Open the ItemDetailPage.xaml.cs file; it is inherited from LayoutAwarePage, which implements functionality such as GoHome and GoBack to navigate the stack of pages. Inside LoadState method it binds last clicked item and its group and group items.     

  •  protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)

            {

                // Allow saved page state to override the initial item to display

                if (pageState != null && pageState.ContainsKey(“SelectedItem”))

                {

                    navigationParameter = pageState[“SelectedItem”];

                }

     

                // TODO: Create an appropriate data model for your problem domain to replace the sample data

                var item = SampleDataSource.GetItem((String)navigationParameter);

                this.DefaultViewModel[“Group”] = item.Group;

                this.DefaultViewModel[“Items”] = item.Group.Items;

                this.flipView.SelectedItem = item;

            }

                  

  • Open the GroupDetailPage.xaml file. This page displays the category’s/Groups’s image and text on the left and then uses a GridView to display the items in the category.

                      

  • Open the GroupDetailPage.xaml.cs file. It also inherits from LayoutAwarePage and gets the GoHome and GoBack methods from this parent. At the end open the SampleDataSource.cs file and move to the definition of the SampleDataSource class. This class creates collections and items using dummy data.                

  • public sealed class SampleDataSource

        {

            private static SampleDataSource _sampleDataSource = new SampleDataSource();

     

            private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>();

            public ObservableCollection<SampleDataGroup> AllGroups

            {

                get { return this._allGroups; }

            }

Summary…..

In this tutorial you learnt Grid View (XAML) template and understand the structure of the project and files included in the project and navigation between pages and how data is bound to the Grid Control. Hope this can help you get excite about window 8 development. Please feel free to comment and share your thoughts.

In my next article I will explain how to modify SampleDataSource to use real data.