Aplicativos modernos

Uma visão do projeto e controle Hub nos Aplicativos da Windows Store

Rachel Appel

Quando se trata de desenvolvimento no Windows com o Visual Studio, os modelos de projeto internos são um bom ponto de partida. Se você não tem experiência em desenvolvimento da Windows Store (ou em alguma pilha da Microsoft), os modelos podem servir como uma ferramenta de aprendizagem. Neste artigo, observarei o controle Hub, mas no contexto do modelo do projeto Hub. Examinarei todos os itens importantes a saber sobre o projeto e controle Hub para aplicativo HTML e XAML.

O projeto Hub, particularmente, permite que você forneça um grande volume de conteúdo ao usuário enquanto usa uma experiência de usuário moderna. Isso porque você pode quebrar o conteúdo do aplicativo em partes chamadas HubSections para que o aplicativo não impressione o usuário visualmente com grandes quantidades de dados. Embora essa seja apenas minha opinião, acho o projeto Hub o mais esteticamente interessante de todos os modelos de aplicativo da Windows Store. O layout do conteúdo está em seções distintas que são fáceis de digerir. Você pode fazer uma demonstração de uma parte favorita do conteúdo na seção "hero" à frente e no centro de tudo, enquanto os itens restantes do conteúdo podem ser facilmente acessados em grupos.

É claro que não é obrigatório que você use os modelos; você pode iniciar de um projeto em branco. No entanto, para muitos desenvolvedores, é muito mais fácil personalizar e expandir os modelos, pois o código é configurado para você.

O modelo do projeto Hub

O Visual Studio 2013 contém modelos do projeto Hub para HTML e XAML. Na criação de um novo projeto HTML usando o modelo, você verá algumas pastas de projeto familiares, como a css, images e js. Além das pastas tradicionais, há as pastas específicas do Hub: pages\hub, pages\item e pages\section. Como é de se esperar, cada uma dessas pastas contém arquivos que correspondem à sua finalidade no aplicativo. Na raiz do projeto está o arquivo para o manifesto do pacote, bem como default.html, o ponto de partida do aplicativo, que carrega default.js e executa funções relacionadas ao gerenciamento do ciclo de vida e do aplicativo. Default.hmtl contém referências não apenas ao arquivo \js\default.js, mas também a \js\data.js, que contém dados de exemplo, e \js\navigator.js, que executa a navegação. Para relembrar a navegação, veja minha coluna de agosto de 2013, "Noções básicas de navegação nos aplicativos da Windows Store", em msdn.microsoft.com/magazine/dn342878. Resumindo, o modelo do projeto Hub, como outros modelos, é uma maneira rápida de publicar aplicativos modernos visualmente interessantes.

É claro que o ponto central do projeto Hub é o controle Hub. Embora default.html seja o ponto de partida do projeto em um aplicativo criado com a Biblioteca do Windows para JavaScript (WinJS), uma vez carregado, ele navega imediatamente para o arquivo hub.html. Hub.html contém o controle Hub e reside no diretório \pages\hub. O controle Hub é o que você usa para criar um layout moderno que é mais do que apenas grupos entediantes de quadrados. Em vez disso, o controle Hub, aliado à busca de dados assíncrona, permite que você apresente grandes quantidades de dados (ou dados que possuem grupos distintos) de maneira organizada, porém, moderna.

O modelo do Hub implementa o hub ou o padrão de navegação, ou hierárquico. Isso significa que, do ponto de partida (isto é, da página do hub), o usuário pode navegar para uma página que contenha todos os membros de uma seção específica ou pode navegar para um item individual. O modelo também contém navegação de uma página de seção para uma página de item. Embora o modelo contenha código de navegação apenas entre a seção 3 e seus grupos e itens (veja a Figura 1), você pode usar os controles ListView ou Repeater para fazer o mesmo tipo de navegação para outras seções, caso isso faça sentido para seu aplicativo. A Figura 1 ilustra a aparência do aplicativo Hub padrão com dados de exemplo no tempo de execução.




Figura 1 O controle Hub no tempo de execução para aplicativos HTML e XAML

Com o restante do Windows vem a ideia de colocar conteúdo à frente e no centro de tudo e, como você pode ver, esse modelo faz exatamente isso.

O projeto modelo Hub XAML funciona, conceitualmente, do mesmo modo que o modelo HTML, contando com o hub como o principal ponto de entrada, sendo navegável para seções e detalhes. É claro que a implementação é diferente, e você pode ver isso examinando a estrutura de pasta, que revela os seguintes diretórios: Assets, Common, DataModel e Strings. Essas pastas contêm o que você pode esperar: ativos como elementos gráficos, dados na pasta DataModel e cadeias de caracteres localizadas na pasta Strings. Na raiz do projeto estão os seguintes arquivos de trabalho necessários para que o aplicativo possa ser executado:

  • App.xaml/.cs: esse é o equivalente XAML de default.html. Ele tem uma minúscula parte de código que auxilia na navegação e nas tarefas gerais.
  • HubPage.xaml/.cs: esse arquivo é a menina dos olhos do aplicativo, contendo o controle Hub.
  • ItemPage.xaml/.cs: esse arquivo contém os itens individuais para os quais você pode navegar das páginas de seção ou do hub.
  • SectionPage.xaml/.cs: esse arquivo mostra todos os membros de dados individuais que pertencem a um determinado grupo.
  • Package.appmanifest: contém as configurações do aplicativo.

O arquivo HubPage.xaml do modelo do projeto Hub XAML revela que o controle Hub se fixa firmemente em um controle Grid que serve como o contêiner raiz para a página e o Hub.

Na pasta DataModel há um arquivo chamado SampleData.json, que contém dados de exemplo. Também nessa pasta, há o arquivo SampleDataSource.cs, que transforma os dados JSON em classes utilizáveis para consumo do C# ou Visual Basic .NET e vinculação de dados XAML. Você pode substituí-lo por seus próprios dados, de forma parecida ao arquivo data.js nos aplicativos do WinJS.

A pasta Common contém vários arquivos que executam inúmeras tarefas, como navegação e outras geralmente relacionadas a aplicativos para trabalho com dados nos modelos de exibição. Além disso, a pasta Common contém o arquivo SuspensionManager.cs, que executa tarefas do ciclo de vida do processo. Por fim, a pasta Strings contém cadeias de caracteres localizadas para publicação em localidades diferentes.

O controle Hub

Os modelos de projeto HTML e XAML usam o controle Hub. Nos aplicativos HTML, o controle Hub funciona como qualquer outro controle do WinJS. Use o atributo data-win-control de um elemento HTML, geralmente um <div>, para defini-lo como um controle Hub, como mostra este código:

<div class="hub" data-win-control="WinJS.UI.Hub"></div>

Isso significa que o objeto WinJS.UI.Hub é o cérebro por trás do controle Hub. O controle Hub atua como um contêiner dos controles HubSection, que definem seções ou grupos de dados. HubSections podem conter qualquer marca HTML válida, como <div> ou <img>, ou um controle WinJS, como o controle ListView. Por padrão, o controle Hub do arquivo hub.html engloba cinco seções, uma denominada hero e quatro mais designadas pelos seus atributos de classe (como section1, section2 e assim por diante). Nos HubSections, as marcas <div> e <img> são os elementos filho mais comuns, mas qualquer controle HTML ou WinJS válido funcionará para exibir dados em um layout diferente. Alterar o layout é uma excelente maneira de personalizar seu aplicativo, mas não se esqueça de seguir as diretrizes da experiência de usuário do Windows, em bit.ly/1gBDHaW. A Figura 2 mostra um exemplo completo de HTML necessário (você verá sua CSS posteriormente) para criar um controle Hub com cinco seções. Examinando o código na Figura 2, vemos que a seção 3 é a seção navegável, enquanto o restante não é.

Figura 2 O HTML que cria o controle Hub

<div class="hub" data-win-control="WinJS.UI.Hub">
  <div class="hero" data-win-control="WinJS.UI.HubSection"></div>
  <div class="section1" data-win-control="WinJS.UI.HubSection"
     data-win-options="{ isHeaderStatic: true }"
     data-win-res="{ winControl: {'header': 'Section1'} }">
    <img src="/images/gray.png" width="420" height="280" />
    <div class="subtext win-type-x-large" data-win-res="
      { textContent: 'Section1Subtext' }"></div>
    <div class="win-type-medium"
       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
    </div>
  </div>
  <div class="section2" data-win-control="WinJS.UI.HubSection" data-win-options="{
 isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section2'} }">
  <div class="item-title win-type-medium" data-win-res="{ textContent: 'Section2ItemTitle' }"></div>
    <div class="article-header win-type-x-large" data-win-res="{ textContent: 'Section2Subtext' }"></div>
    <div class="win-type-xx-small" data-win-res="{ textContent: 'Section2ItemSubTitle' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
    </div>
  </div>
  <div class="section3" data-win-control="WinJS.UI.HubSection" data-win-res="{
 winControl: {'header': 'Section3'} } "data-win-options="{
    onheaderinvoked: select('.pagecontrol').winControl.section3HeaderNavigate }">
    <div class="itemTemplate" data-win-control="WinJS.Binding.Template">
      <img src="#" data-win-bind="src: backgroundImage; alt: title" />
      <div class="win-type-medium" data-win-bind="textContent: title"></div>
      <div class="win-type-small" data-win-bind="textContent: description"></div>
      </div>
      <div class="itemslist win-selectionstylefilled" data-win-control="WinJS.UI.ListView"
        data-win-options="{layout: {type: WinJS.UI.GridLayout},
        selectionMode: 'none', itemTemplate: select('.section3 .itemTemplate'),
        itemDataSource:select('.pagecontrol').winControl.section3DataSource,
         oniteminvoked: select('.pagecontrol').winControl.section3ItemNavigate }">
      </div>
    </div>
  <div class="section4" data-win-control="WinJS.UI.HubSection" data-win-options="{
   isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section4'} }">
    <div class="top-image-row">
      <img src="/images/gray.png" />
    </div>
    <div class="sub-image-row">
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
    </div>
    <div class="win-type-medium"       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
    </div>
  </div>
</div>

Em XAML, o controle Hub usa um elemento <Hub> que contém os elementos <Hub.Header> e <HubSection>. Sucessivamente, os títulos e seções filho contêm Grid e outros controles XAML, como o StackPanel, bem como blocos de texto. A Figura 3 mostra o XAML exigido para criar o controle Hub usado nos modelos do Visual Studio.

Figura 3 O XAML para um controle Hub

<Hub SectionHeaderClick="Hub_SectionHeaderClick">
  <Hub.Header>
    <!-- Back button and page title -->
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="80"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Button  x:Name="backButton" Style="{StaticResource NavigationBackButtonNormalStyle}"
        Margin="-1,-1,39,0"
        VerticalAlignment="Top"
        Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
        AutomationProperties.Name="Back"
        AutomationProperties.AutomationId="BackButton"
        AutomationProperties.ItemType="Navigation Button"/>
      <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}"
        Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
        VerticalAlignment="Top" IsHitTestVisible="false" TextWrapping="NoWrap" />
    </Grid>
  </Hub.Header>
  <HubSection Width="780" Margin="0,0,80,0">
    <HubSection.Background>
      <ImageBrush ImageSource="Assets/MediumGray.png" Stretch="UniformToFill" />
    </HubSection.Background>
  </HubSection>
  <HubSection Width="500" x:Uid="Section1Header" Header="Section 1">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png" Stretch="Fill" Width="420" Height="280"/>
          <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
            Grid.Row="1" Margin="0,10,0,0" TextWrapping="Wrap"
            x:Uid="Section1Subtitle" Text="Lorem ipsum dolor sit nonumy sed consectetuer ising elit, sed diam"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
            Grid.Row="2" Margin="0,10,0,0" x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
            x:Uid="Section1DescriptionText" Text="Lorem ipsum dolor sit amet... "/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection Width="520" x:Uid="Section2Header" Header="Section 2">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Style="{StaticResource TitleTextBlockStyle}"
           Margin="0,0,0,10" x:Uid="ItemTitle" Text="Item Title" />
        <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
           Grid.Row="1" x:Uid="Section2UnderTitle" Text="Quisque in porta
           lorem dolor amet sed consectetuer ising elit, sed diam non
           my nibh uis mod wisi quip."/>
        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}"
           Grid.Row="2" Margin="0,20,0,0" x:Uid="ItemSubTitle"
           Text="Item Sub Title"/>
        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
          x:Uid="LongText" Text="Lorem ipsum dolor sit amet..."/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection IsHeaderInteractive="True"
     DataContext="{Binding Section3Items}" d:DataContext="{Binding Groups[3],
     Source={d:DesignData Source=/DataModel/SampleData.json,
     Type=data:SampleDataSource}}" x:Uid="Section3Header" Header="Section 3"
     Padding="40,40,40,32">
    <DataTemplate>
      <GridView
        x:Name="itemGridView"
        ItemsSource="{Binding Items}"
        Margin="-9,-14,0,0"
        AutomationProperties.AutomationId="ItemGridView"
        AutomationProperties.Name="Items In Group"
        ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="ItemView_ItemClick">
      </GridView>
    </DataTemplate>
  </HubSection>
  <HubSection x:Uid="Section4Header" Header="Section 4">
    <DataTemplate>
      <!-- width of 400 -->
      <StackPanel Orientation="Vertical">
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="270"/>
            <RowDefinition Height="95"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png"
             Grid.ColumnSpan="5" Margin="0,0,0,10" Stretch="Fill" />
          <Image Source="Assets/MediumGray.png" Grid.Row="1" Stretch="Fill"/>
           <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="2" Stretch="Fill"/>
          <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="4" Stretch="Fill"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
             Grid.Row="2" Grid.ColumnSpan="5"  Margin="0,15,0,0"
            x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}"
             Grid.Row="3" Grid.ColumnSpan="5" x:Uid="LongText"
             Text="Lorem ipsum dolor sit amet...."/>
        </Grid>
      </StackPanel>
    </DataTemplate>
  </HubSection>
</Hub>

Como você pode ver, a sintaxe XAML é um pouco mais detalhada do que a sintaxe HTML. Isso porque você codifica o layout e os estilos diretamente na página XAML (embora os estilos XAML possam ser colocados em um dicionário de recursos), enquanto no HTML, as regras de layout e estilo são CSS (mais sobre definição de estilo posteriormente).

Vinculação de dados e o controle Hub

Matrizes ou JSON (que geralmente serializa para uma matriz) são as maneiras tradicionais de trabalhar com dados no WinJS, bem como em muitas outras linguagens de cliente e da Web. Isso não é diferente com o projeto Hub. No entanto, você pode substituir os dados em \js\data.js por dados personalizados divididos em muitos grupos que você planeja usar. Você encontrará duas matrizes como dados de exemplo no arquivo data.js, uma para agrupamento e outra para itens individuais que são associados a um grupo específico. Se estiver familiarizado com alguns dos outros modelos do projeto WinJS, você perceberá que esses são os mesmos dados de exemplo.

No arquivo \pages\hub\hub.js estão as chamadas aos membros do namespace Data que obtêm dados de item e grupo:

var section3Group = Data.resolveGroupReference("group4");
var section3Items = Data.getItemsFromGroup(section3Group);

section3Group e section3Items são objetos globais. A Figura 2 mostra a sintaxe da vinculação de dados para o controle ListView. Em hub.js, após a função ready, o código define section3DataSource, uma propriedade do controle Hub:

section3DataSource: section3Items.dataSource,

O controle Hub usa o código anterior para vincular dados ao ListView (a Figura 2 mostra o código ListView vinculado por dados).

Em aplicativos XAML usando C#, você tem as mesmas ocorrências básicas, pois o código do arquivo HubPage.xaml.cs indica a seguinte declaração para um modelo de exibição do tipo ObservableDictionary, juntamente com sua declaração de propriedade correspondente (onde é possível retornar seus próprios dados):

private ObservableDictionary defaultViewModel = new ObservableDictionary();
public ObservableDictionary DefaultViewModel
{
  get { return this.defaultViewModel; }
}

Mais adiante no arquivo, o código define um modelo de exibição de nível de página chamando GetGroupAsync, que, como diz o nome, é executado de modo assíncrono: 

var sampleDataGroup = await SampleDataSource.GetGroupAsync("Group-4");

Embora a chamada obtenha dados de Group-4, você a atribui a um modelo de exibição denominado Section3Items para atribuí-lo a esses itens. Considere a seção hero como Section 0, o que significa que os itens de Section 3 se alinharão com os dados de Group-4:

this.DefaultViewModel["Section3Items"] = sampleDataGroup;

Isso é tudo o que você precisa no code-behind. Em XAML, observe que o atributo DataContext se associa a Section3Items. Os outros atributos não são necessários para vinculação de dados, mas agem como um auxílio para as ferramentas de design no Visual Studio ou Blend, conforme designado pelo namespace "d":

<HubSection IsHeaderInteractive="True" DataContext="{Binding Section3Items}" 
  d:DataContext="{Binding Groups[3], Source={d:DesignData
  Source=/DataModel/SampleData.json, Type=data:SampleDataSource}}"
  x:Uid="Section3Header" Header="Section 3" Padding="40,40,40,32">

Embora esteja trabalhando com dados de exemplo locais, você tem muitas opções de acesso a dados, incluindo File IO, SQLite, Web Storage, IndexedDB, serviços REST e Windows Azure, apenas para citar alguns. Se desejar analisar quais opções de dados estão disponíveis, veja meu artigo de março de 2013, "Opções de acesso a dados e armazenamento em aplicativos da Windows Store", em msdn.microsoft.com/magazine/jj991982.

Criando estilos para o controle Hub

Nos aplicativos da Windows Store criados com JavaScript, você pode definir estilos para o controle Hub com a CSS. O arquivo \hub\hub.css contém toda a CSS padrão relacionada ao controle Hub. Sinta-se à vontade para adicionar seus próprios estilos e alterar o tamanho dos elementos ou seu layout. A Figure 4 mostra a CSS completa no hub.css. Observe que há um seletor de classe .hubpage que usa atributos de função semântica HTML5, como header[role=banner] e section[role=main] para designar os estilos gerais do hub. Depois disso, a CSS na Figura 4 mostra o seletor descendente ".hubpage .hub .hero", que cria a seção apresentada (hero) do controle Hub. O hero preenche, grosso modo, metade do lado esquerdo da parte visível da tela com um plano de fundo cinza claro e, é claro, é uma excelente maneira de colocar uma parte especial de conteúdo onde nenhum usuário deixará de notar! Você pode preenchê-lo com muitos dados, e os dados gráficos ou a multimídia funcionam razoavelmente bem para serem mostrados aqui.

Figura 4 A CSS que molda e define o estilo do controle Hub HTML

.hubpage header[role=banner] {
  position: relative;
  z-index: 2;
}
.hubpage section[role=main] {
  -ms-grid-row: 1;
  -ms-grid-row-span: 2;
  z-index: 1;
}
.hubpage .hub .win-hub-surface {
  height: 100%;
}
.hubpage .hub .hero {
  -ms-high-contrast-adjust: none;
  background-image: url(/images/gray.png);
  background-size: cover;
  margin-left: -80px;
  margin-right: 80px;
  padding: 0;
  width: 780px;
}
  .hubpage .hub .hero:-ms-lang(
    ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab,
     syr, ug, ur, qps-plocm) {
    margin-left: 80px;
    margin-right: -80px;
  }
  .hubpage .hub .hero .win-hub-section-header {
    display: none;
  }
  .hubpage .hub .section1 {
    width: 420px;
  }
  .hubpage .hub .section1 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section1 .subtext {
    margin-bottom: 7px;
    margin-top: 9px;
  }
.hubpage .hub .section2 {
  width: 440px;
}
  .hubpage .hub .section2 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section2 .item-title {
      margin-top: 4px;
      margin-bottom: 10px;
  }
  .hubpage .hub .section2 .article-header {
    margin-bottom: 15px;
  }
.hubpage .hub .section3 {
}
  .hubpage .hub .section3 .itemslist {
    height: 100%;
    margin-left: -10px;
    margin-right: -10px;
    margin-top: -5px;
  }
  .hubpage .hub .section3 .win-container {
    margin-bottom: 36px;
    margin-left: 10px;
    margin-right: 10px;
  }
  .hubpage .hub .section3 .win-item {
      height: 229px;
      width: 310px;
  }
      .hubpage .hub .section3 .win-item img {
        height: 150px;
        margin-bottom: 10px;
        width: 310px;
      }
.hubpage .hub .section4 {
  width: 400px;
}
  .hubpage .hub .section4 .win-hub-section-content {
        overflow-y: hidden;
  }
  .hubpage .hub .section4 .top-image-row {
    height: 260px;
    margin-bottom: 10px;
    width: 400px;
  }
    .hubpage .hub .section4 .top-image-row img {
      height: 100%;
       width: 100%;
    }
.hubpage .hub .section4 .sub-image-row {
  margin-bottom: 20px;
  display: -ms-flexbox;
  -ms-flex-flow: row nowrap;
  -ms-flex-pack: justify;
}
  .hubpage .hub .section4 .sub-image-row img {
    height: 95px;
     width: 130px;
  }

Como você pode ver, a CSS na Figura 4 molda e define o estilo do controle Hub e a maior parte dela lida com o layout e o dimensionamento dos HubSections. Elementos e controles do WinJS dentro de HubSections aplicam os estilos de ui-light.css ou ui-dark.css, até que você os substitua pelos seus próprios estilos.

Os aplicativos HTML contam com a CSS para definição de estilo. Os aplicativos XAML contam com a XAML para definição de estilo. Isso significa que a XAML tem vários atributos que você aplica a marcas para impor definições de estilo chamadas de recursos. Por exemplo, o código que define o estilo de um TextBlock é o atributo Style e faz referência a um estilo interno (dicionário de recursos estáticos) denominado SubheaderTextBlockStyle:

<TextBlock Style="{StaticResource SubheaderTextBlockStyle} />

O layout de uma página também é XAML, pois todos os Hubs, Grids e outros elementos contêm coordenadas embutidas para suas posição na tela, bem como o tamanho. Você pode ver em toda a Figura 3 que há margens, posicionamento e configurações de linha e coluna que posicionam elementos, tudo embutido no XAML. O HTML, originalmente, é uma tecnologia da Web e conservar largura de banda usando CSS em vez de HTML é um benefício real. Aqui na terra do XAML, é tudo do lado do cliente, de modo que o cache da interface do usuário não é um grande problema e os estilos podem ser embutidos. Um lado positivo do XAML é que você não precisa fazer muito esforço para garantir um design com capacidade de resposta. Basta garantir a definição de dois elementos <RowDefinition> para uma altura "Auto" e "*":

<Grid.RowDefinitions>
  <RowDefinition Height="Auto"/>
  <RowDefinition Height="*"/>
</Grid.RowDefinitions>

As linhas responderão automaticamente às alterações do estado de exibição do aplicativo, tornando o layout fluido enquanto salva código extra. A Figura 3 mostra algumas referências às definições de linha de altura automática. 

Exemplos disponíveis

Depois de modificar o controle Hub, executar a recuperação e a vinculação de dados e definir estilos, você está pronto para seguir. Não se esqueça de adicionar toques modernos, como blocos, pesquisa e outras integrações do Windows ao seu aplicativo. O modelo do projeto Hub é uma maneira fácil de criar e publicar aplicativos rapidamente, em HTML ou XAML. Usar o padrão de navegação de hub com o controle Hub permite criar uma experiência de usuário rica e eficaz que segue os princípios da interface de usuário moderna. Você pode baixar os exemplos do controle Hub que cobrem muitos aspectos do desenvolvimento de aplicativos Windows nos seguintes locais:

Rachel Appel é consultora, autora, mentora e antiga funcionária da Microsoft com mais de 20 anos de experiência no setor de TI. Ela dá palestras em importantes congressos do setor, como o Visual Studio Live!, o DevConnections, o MIX e muitos outros. Sua experiência está ligada a soluções de desenvolvimento que alinham negócios e tecnologia com foco na pilha de desenvolvimento da Microsoft e em Web aberta. Para obter mais informações sobre a Appel, visite seu site em rachelappel.com.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Frank La Vigne (Microsoft)