Part 15 - Understanding the Hub App Template Overview and Navigation

Play Part 15 - Understanding the Hub App Template Overview and Navigation
Sign in to queue

Description

In this lesson, we’ll learn about the Hub App template.  If you’re familiar with the Windows Phone, you’ll have seen instances of the Hub in use.   There is so much here that we’ll spend the majority of the remaining series talking about this template, the technologies it uses, and how to modify it and extend it to get the results we want.  That’s no small matter.

As a part of this lesson we will:

(1) Create a new Hub App Template project called “HubAppTemplate”

(2) Run the app.  Note the navigation.  Tie the navigation to pages in the project.

(3) Open the HubPage.xaml and roll up the major sections … they will primarily break down into: DataTemplates and HubSections.

Begin by creating a “throw away” project using the Hub App Template.

So, let’s talk about a high level about how this app works and then we’ll drill down into each of the pieces.

At the highest level is the Hub control which allows you to create a series of panels, or rather, HubSections.  You can see there are five HubSections that correspond to the five panels in our app.

Each HubSection is comprised of (a) data and (b) a template that defines how that data should be displayed.  So, two parts, data and a data template.

I’ll talk about the source of the data in just a moment.  However, let’s take a look at the data templates.  If we drill into a given HubSection like “SECTION 2”:

<HubSection x:Uid="Section2Header"
            Header="SECTION 2"
            Width="Auto"
            DataContext="{Binding Section2Items}"
              d:DataContext="{Binding Groups[1],
                Source={d:DesignData
                  Source=./DataModel/SampleData.json,Type=data:SampleDataSource}}">
  <DataTemplate>
    <GridView ItemsSource="{Binding Items}"                       
              AutomationProperties.AutomationId="ItemGridView"
              AutomationProperties.Name="Items In Group"
              ItemTemplate="{StaticResource Standard200x180TileItemTemplate}"
              SelectionMode="None"
              IsItemClickEnabled="True"
              ItemClick="ItemView_ItemClick">
      <GridView.ItemsPanel>
        <ItemsPanelTemplate>
          <ItemsWrapGrid />
        </ItemsPanelTemplate>
      </GridView.ItemsPanel>
    </GridView>
  </DataTemplate>
</HubSection>

There’s a lot going on here.  That’s because this is employing a whole framework of templating in order to make it extremely flexible.  The unfortunate trade off to making a technology very flexible is often complexity, at least at first.  However, it’s all logical, so if you can just understand the logic behind it, if you can build a mental model, you can at a minimum be able to command it to do what you need it to by force with a lot of trial and error.

Besides the properties of the HubSection itself which I’ll ignore for now because it has to do with the data, the HubSection has a child called DataTemplate.  The DataTemplate is a GridView … similar to a Grid control that we’ve used for layout, but it supports binding to data.  The GridView represents this entire area in “SECTION 2”.  The GridView’s ItemsPanel controls the flow of each individual item in the GridView.  So, you have a collection of items.  Will they flow horizontally or vertically?  In this case, the ItemsWrapGrid by default will position each child elements sequentially from top to bottom. When elements extend beyond the container edge (the bottom, in this case), elements are positioned in the next column.

So, The ItemsPanel uses the ItemsWrapGrid to layout each item in our data in a certain flow direction, from top to bottom, then left to right.

But what about the layout of each individual item in our data?  The GridView’s ItemTemplate="{StaticResource Standard200x180TileItemTemplate} property dictates that.  As you can see, it is binding to a StaticResource called Standard200x180TileItemTemplate which is defined in the Page.Resources section:

<Page.Resources>
  <!-- Grid-appropriate item template as seen in section 2 -->
  <DataTemplate x:Key="Standard200x180TileItemTemplate">
    <Grid Width="180">
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
      </Grid.RowDefinitions>
      <Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
              Height="173"
              Width="173"
              Grid.Row="0"
              HorizontalAlignment="Left">
          <Image Source="{Binding ImagePath}"
               Stretch="UniformToFill"
               AutomationProperties.Name="{Binding Title}"
               Height="173"
               Width="173"/>
        </Border>
        <TextBlock Text="{Binding Title}"
                   Style="{ThemeResource BaseTextBlockStyle}"
                   Typography.Capitals="SmallCaps"
                   Grid.Row="1"
                   Margin="0,12,0,0"
                   IsTextScaleFactorEnabled="False"/>
      </Grid>
    </DataTemplate>

Each individual items is made up of a Grid that is 180 pixels wide.  The grid defines two rows.  The first row is filled with an border that contains an image, these gray images we see in the designer.  I think the Border is just there in case the image cannot be displayed, or perhaps it provides a themed background color for transparent images.  I’m not really sure of the purpose, but I think that will be the result. 

The second row is filled with a TextBlock, the “Item Title: 1” and so forth.

So, now we understand how each item in our data source will be rendered to screen for “Section 2”.  Admittedly, there are many tiny details I’m overlooking, but I can perform a search online for their meaning.  I highly encourage you to do the research when you come across something that is not obvious by just reading it’s name or setting.

For example, I refrained from talking about the <TextBlock Typography.Capitals=”SmallCaps” /> because I give you enough credit to be able to look at that and understand what it is doing when you see the results on screen:

clip_image002

However, the <TextBlock IsTextScaleFactorEnabled=”False” /> is not, at least to me, quite as obvious.  So, I’ll perform a search online to learn more about it.

Back in the GridView definition, there are three properties that affect navigation:

<GridView                        
  . . .
  SelectionMode="None"
  IsItemClickEnabled="True"
  ItemClick="ItemView_ItemClick">
</GridView>

Setting SelectionMode to none means that we’re not allowing individual items to be selected, as if there were a list of items that we’re selecting for inclusion in some operation. 

Instead, we want to allow the user to click a given item and perform a navigation operation.  Setting IsItemClickEnabled=”True” instructs the GridView how we want a tap to be interpreted.  We want a tap on a given item to trigger an event called ItemClick, not a selection event called ItemSelected.  The semantic difference of those two interactions is very important.

The ItemClick=”ItemView_ItemClick” wires up an event handler to the ItemClick event.

If we navigate to that event handler in our code behind, we find the following definition:

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(ItemPage), itemId);
}

The first line of code is retrieving the clicked item from the ItemClickEventArgs and then casting it to an instance of the class that we’re binding to.  This SampleDataItem class is just sample data provided by the Hub App Template so that you can see some data when you run the application.  We’ll investigate that class in the next lesson.  For now, just understand that it has a property called UniqueId.  We’re retrieving that UniqueId that presumably uniquely identifies the specific item that was tapped amongst the dozen or more items that the user could have tapped.

The next step is simple … navigate to the ItemPage.xaml page passing in the id of the item that we want displayed on that page.

Based on our understanding of the Navigation model and how we can retrieve the object that was passed from one page to the next, we might think we know what happens on the ItemPage.xaml.  We would expect to handle the OnNavigatedTo() method like we’ve done before.

However, if we were to look at the ItemPage.xaml.cs file, you’ll find no such method declared.  Instead, we see that the Hub App Template relies on a class called NavigationHelper to perform some repetitive tasks related to navigation and passing data between pages.

The NavigationHelper.cs file is located in the \Common folder.  If you’re following along, take a moment to read the lengthy explanation in the comments about what this class does and how to use it.  In a nut shell, it handles state management for you, allowing users to return to the exact page in your app where they left off in their previous session.  I would recommend that you do not make any changes to this class for now.

So, I’ll just pluck out the lines of code that are used to enable the use of the NavigationHelper class from within the ItemPage.xaml.cs (in other words, I’m removing all the code that doesn’t deal with navigation in the following code just so you can easily isolate what has been added to work with the NavigationHelper class):

    public sealed partial class ItemPage : Page
    {
        private NavigationHelper navigationHelper;

        public NavigationHelper NavigationHelper
        {
            get { return this.navigationHelper; }
        }

        public ItemPage()
        {
            this.navigationHelper = new NavigationHelper(this);
            this.navigationHelper.LoadState += navigationHelper_LoadState;
        }
  
        private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
            var item = await SampleDataSource.GetItemAsync((String)e.NavigationParameter);
            this.DefaultViewModel["Item"] = item;
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedFrom(e);
        }

        #endregion
    }

In a nut shell:

(a) A new instance of NavigationHelper is created and its reference is available throughout the ItemPage class.
(b) In order to keep the NavigationHelper class in the loop about navigation to and from this page, the page’s OnNavigatedTo and OnNavigatedFrom methods turn around and call similar methods on the NavigationHelper.
(c) In the constructor, the navigationHelper_LoadState method is wired up.  It will be triggered by the NavigationHelper class when the page is navigated to.  In the navigationHelper_LoadState event handler the data associated with the item that was clicked on will be retrieved and set as the source of data for the current page.

Recap

I want to stop there.  There are many other features of the Hub App Template that we’ll learn about in the following lessons.  In this lesson, I focused on the overall layout and templating of the Hub control and the navigation technique that was employed.  In the next lesson, we’ll learn about the sample data and how the various templates bind to it for display.

Embed

Download

Download this episode

The Discussion

  • User profile image
    bilalmustafa

    Bob, The way you explained the things is amazing.

  • User profile image
    Malick

    Hi
    I want to ask if am making an menu card and all hub section would of same data template so how can I create hub sections dynamically on run time as my categories in menu increases the hub section built it self with same data template

    I would be very thank full if you can help me out

    Regards
    Malick

  • User profile image
    Pratap

    Good joob , explain in easy way
    moreover, I couldn't find the HUB Template in Visual Studio 2013
    What to do .???

  • User profile image
    Hocheechern​gmaster

    C#

    Bob, The way you explained the things is amazing.

Add Your 2 Cents