Windows 应用商店应用程序中的 Hub 项目和控件一览


Windows 应用商店应用程序中的 Hub 项目和控件一览

Rachel Appel

通过 Visual Studio 在 Windows 上进行开发时,使用内置项目模板是一个不错的起点。 如果您初次接触 Windows 应用商店(或任何 Microsoft 堆栈)开发,可以将模板作为学习工具。 在本文中,我将基于 Hub 项目模板介绍 Hub 控件。 您将会了解有关适用于 HTML 和 XAML 应用程序的 Hub 项目和控件的所有重要内容。

值得一提的是,通过 Hub 项目,您可以使用新型用户体验向用户提供大量内容。 这是因为 Hub 项目将应用程序的内容分解为多个被称为 HubSection 的部分,使得用户不会因看到大量数据而感到难以应付。 我认为在所有 Windows 应用商店应用程序模板当中,Hub 项目从美观角度来看是最吸引人的,尽管这只是我个人的观点。 内容布局划分为多个易于把握的不同部分。 您可以在该中心醒目的“hero”节展示最喜爱的内容,而将其余内容项分组放置,以方便访问。

当然,使用模板并不是必需的 — 可以从创建一个空白项目开始。 不过,对于许多开发人员来说,对模板进行自定义并进行扩展要容易得多,因为代码已为您设置好。

Hub 项目模板

Visual Studio 2013 包含用于 HTML 和 XAML 的 Hub 项目模板。 使用该模板创建新 HTML 项目时,您会看到一些熟悉的项目文件夹,如 css、images 和 js 文件夹。 除惯用的文件夹外,还有 Hub 特定文件夹:pages\hub、pages\item 和 pages\section。 正如您可能期望的那样,其中每个文件夹都包含对应于它们在应用程序中的用途的文件。 项目根中包含用于包清单的文件以及作为应用程序起点的 default.html,后者加载 default.js 并执行与应用程序和生命周期管理相关的功能。 Default.html 不仅包含对 \js\default.js 文件的引用,而且包含对 \js\data.js(包含示例数据)和 \js\navigator.js(执行导航)的引用。 关于导航的简要介绍,请参见我在 2013 年 8 月撰写的专栏文章“在 Windows 应用商店应用程序中导航的基础知识”(位于 msdn.microsoft.com/magazine/dn342878)。 简言之,Hub 项目模板与其他模板一样,是发布炫目新型应用程序的一种快速方法。

当然,Hub 项目的核心是 Hub 控件。 default.html 是使用 Windows JavaScript 库 (WinJS) 生成应用程序时的项目起点,一旦加载,它就会立即导航到 hub.html 文件。 Hub.html 包含 Hub 控件并位于 \pages\hub 目录中。 Hub 控件可用来创建由并不枯燥的几组方块组成的现代布局。 Hub 控件与异步数据提取相结合,以有序而新颖的方式展示大量数据或不同组的数据。

Hub 模板可实现中心导航或分层导航模式。 这意味着,用户可从起点(即中心页面)导航到包含特定节所有成员的页面,或者,用户可以从中心页面导航到单个项。 该模板还包含从节页面到项页面的导航。 虽然该模板仅包含第 3 节及其组和项之间的导航代码(请参见图 1),但您可以使用 ListView 或 Repeater 控件,针对其他节执行相同类型的导航(如果这对于您的应用程序来说有意义)。 图 1 演示了含有示例数据的默认 Hub 应用程序在运行时的外观。




图 1 HTML 和 XAML 应用程序 Hub 控件的运行结果

随着 Windows 的重塑,人们倾向于将内容放到前端和中心,您可以看到,此模板就是这样做的。

XAML Hub 模板项目的工作原理与 HTML 相同,也依赖于将中心作为主入口点,可导航至各节和详细内容。 当然,实现方式是不同的,您可从文件夹结构了解这一点,此文件夹结构显示了以下目录:Assets、Common、DataModel 和 Strings。 这些文件夹包含您可能期望得到的内容:资源,如 DataModel 文件夹中的图形和数据以及 Strings 文件夹中的本地化字符串。 在项目的根目录中,为了应用程序能够运行,需要有以下工作文件:

  • App.xaml/.cs:这是 default.html 的 XAML 等效文件。 它含有少量辅助导航和完成常规任务的代码。
  • HubPage.xaml/.cs:这是应用程序的最重要部分,包含 Hub 控件。
  • ItemPage.xaml/.cs:此文件包含您可从中心或节页面导航到的各个项。
  • SectionPage.xaml/.cs:此文件显示属于特定组的所有数据成员。
  • Package.appmanifest:此文件包含应用程序设置。

XAML Hub 项目模板的 HubPage.xaml 文件显示,Hub 控件将其自身牢牢固定在用作页面和中心的根容器的 Grid 控件中。

在 DataModel 文件夹中,有一个名为 SampleData.json 的含有示例数据的文件。 在该文件夹中,还有一个 SampleDataSource.cs 文件,此文件将 JSON 数据转换为可使用的类,用于 C# 或 Visual Basic .NET 使用和 XAML 数据绑定。 您可以用自己的数据替换这种数据,这与 WinJS 应用程序中的 data.js 文件非常相似。

Common 文件夹包含多个文件,这些文件可执行各种任务,如导航以及在视图模型中使用数据、通常与应用程序相关的其他任务。 另外,Common 文件夹还包含 SuspensionManager.cs 文件,此文件执行进程生命周期任务。 最后,Strings 文件夹包含用于在不同区域设置中发布的本地化字符串。

Hub 控件

HTML 和 XAML 项目模板都使用 Hub 控件。 在 HTML 应用程序中,Hub 控件的工作方式与任何其他 WinJS 控件类似。 使用 HTML 元素的 data-win-control 属性(通常为 <div>),可以将该元素定义为 Hub 控件,如以下代码所示:


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

这意味着 WinJS.UI.Hub 对象是 Hub 控件的大脑。 Hub 控件充当 HubSection 控件的容器,而 HubSection 控件定义数据的节或组。 HubSection 可包含任何有效的 HTML 标记(如 <div> 或 <img>)或 WinJS 控件(如 ListView 控件)。 默认情况下,hub.html 文件的 Hub 控件包含五个节,一个节名为 hero,其他四个节由它们的类属性指定(如 section1、section2 等)。 在 HubSection 中,<div> 和 <img> 标记是最常用的子元素,但任何有效的 HTML 或 WinJS 控件都可用来显示不同布局中的数据。 更改布局是对应用程序进行个性化设置的一个极佳方法,但不要忘记遵守 bit.ly/1gBDHaW 中的 Windows UX 指南。 图 2 显示了创建含有五个节的 Hub 控件所需的 HTML 的一个完整示例(您稍后会看到它的 CSS)。 查看图 2 中的代码可以发现,第 3 节是可导航的节,而其他节都不可导航。

图 2 用于创建 Hub 控件的 HTML


  
  
  1.           <div class="hub" data-win-control="WinJS.UI.Hub">
  2.   <div class="hero" data-win-control="WinJS.UI.HubSection"></div>
  3.   <div class="section1" data-win-control="WinJS.UI.HubSection"
  4.      data-win-options="{ isHeaderStatic: true }"
  5.      data-win-res="{ winControl: {'header': 'Section1'} }">
  6.     <img src="/images/gray.png" width="420" height="280" />
  7.     <div class="subtext win-type-x-large" data-win-res
  8. ="
  9.       { textContent: 'Section1Subtext' }"></div>
  10.     <div class="win-type-medium"
  11.        data-win-res="{ textContent: 'DescriptionText' }"></div>
  12.     <div class="win-type-small">
  13.       <span data-win-res="{ textContent: 'Section1Description' }"></span>
  14.       <span data-win-res="{ textContent: 'Section1Description' }"></span>
  15.       <span data-win-res="{ textContent: 'Section1Description' }"></span>
  16.     </div>
  17.   </div>
  18.   <div class="section2" data-win-control="WinJS.UI.HubSection" data-win-options
  19. ="{
  20.  isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section2'} }">
  21.   <div class="item-title win-type-medium" data-win-res="{ textContent: 'Section2ItemTitle' }"></div>
  22.     <div class="article-header win-type-x-large" data-win-res="{ textContent: 'Section2Subtext' }"></div>
  23.     <div class="win-type-xx-small" data-win-res="{ textContent: 'Section2ItemSubTitle' }"></div>
  24.     <div class="win-type-small">
  25.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  26.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  27.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  28.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  29.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  30.       <span data-win-res="{ textContent: 'Section2Description' }"></span>
  31.     </div>
  32.   </div>
  33.   <div class="section3" data-win-control="WinJS.UI.HubSection" data-win-res
  34. ="{
  35.  winControl: {'header': 'Section3'} } "data-win-options
  36. ="{
  37.     onheaderinvoked: select('.pagecontrol').winControl.section3HeaderNavigate }">
  38.     <div class="itemTemplate" data-win-control="WinJS.Binding.Template">
  39.       <img src="#" data-win-bind="src: backgroundImage; alt: title" />
  40.       <div class="win-type-medium" data-win-bind="textContent: title"></div>
  41.       <div class="win-type-small" data-win-bind="textContent: description"></div>
  42.       </div>
  43.       <div class="itemslist win-selectionstylefilled" data-win-control="WinJS.UI.ListView"
  44.         data-win-options
  45. ="{layout: {type: WinJS.UI.GridLayout},
  46.         selectionMode: 'none', itemTemplate: select('.section3 .itemTemplate'),
  47.         itemDataSource:select('.pagecontrol').winControl.section3DataSource,
  48.          oniteminvoked: select('.pagecontrol').winControl.section3ItemNavigate }">
  49.       </div>
  50.     </div>
  51.   <div class="section4" data-win-control="WinJS.UI.HubSection" data-win-options
  52. ="{
  53.    isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section4'} }">
  54.     <div class="top-image-row">
  55.       <img src="/images/gray.png" />
  56.     </div>
  57.     <div class="sub-image-row">
  58.       <img src="/images/gray.png" />
  59.       <img src="/images/gray.png" />
  60.       <img src="/images/gray.png" />
  61.     </div>
  62.     <div class="win-type-medium"       data-win-res="{ textContent: 'DescriptionText' }"></div>
  63.     <div class="win-type-small">
  64.       <span data-win-res="{ textContent: 'Section4Description' }"></span>
  65.       <span data-win-res="{ textContent: 'Section4Description' }"></span>
  66.     </div>
  67.   </div>
  68. </div>
  69.         

在 XAML 中,Hub 控件使用一个包含 <Hub.Header> 和 <HubSection> 元素的 <Hub> 元素。 反过来,子标题和节又包含 Grid 和其他 XAML 控件(如 StackPanel)以及文本块。 图 3 显示了创建在 Visual Studio 模板中使用的 Hub 控件所需的 XAML。

图 3 Hub 控件的 XAML


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

您可以看到,XAML 语法与 HTML 相比有些冗长。 这是因为,您是在 XAML 页面中对布局和样式进行编码的(不过,可以将 XAML 样式放置在资源字典中),而在 HTML 中,布局和样式规则为 CSS(后面将对样式设置进行更详细的描述)。

数据绑定和 Hub 控件

数组或 JSON(通常会序列化为数组)是在 WinJS 中以及在许多其他 Web 或客户端语言中使用数据的惯用方法。 这对于 Hub 项目没有什么不同。 您可以用将用到的自定义数据(分解为任意数量的组)来替换 \js\data.js 中的数据。 data.js 文件中包含作为示例数据的两个数组,一个数组用于分组,另一个数组用于关联到特定组的各个项。 如果您熟悉某些其他 WinJS 项目模板,就会发现示例数据是相同的。

在 \pages\hub\hub.js 文件中,包含对 Data 命名空间的成员的调用(这些调用可获取组和项数据):


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

section3Group 和 section3Items 是全局对象。 图 2 显示了 ListView 控件的数据绑定语法。 在 ready 函数后面的 hub.js 中,该代码设置 Hub 控件的属性 section3DataSource:


          section3DataSource: section3Items.dataSource,
        

Hub 控件使用前面的代码执行对 ListView 的数据绑定(图 2 显示了数据绑定 ListView 代码)。

在使用 C# 的 XAML 应用程序中,会有相同的基本情况发生,因为 HubPage.xaml.cs 文件中的代码指示出类型为 ObservableDictionary 的视图模型的以下声明及其相应的属性声明(这是您可以返回自己的数据的位置):


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

在该文件的后面,代码会通过调用 GetGroupAsync(顾名思义,它会异步运行)来设置一个页面级视图模型: 


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

虽然该调用获取 Group-4 数据,但您可将其分配给名为 Section3Items 的视图模型以将其分配给这些项。 将 hero 节视为 Section 0,这意味着 Section 3 项将与 Group-4 数据一致:


  
  
  1.           this.DefaultViewModel["Section3Items"] = sampleDataGroup;
  2.         

这是您在代码隐藏中所需全部。 请注意,在 XAML 中,DataContext 属性绑定到 Section3Items。其他属性对于数据绑定来说不是必要的,但可充当 Visual Studio 或 Blend 中的设计工具的辅助工具,由“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">
        

在使用本地示例数据时,您有多种数据访问选项,包括文件 IO、SQLite、Web 存储、IndexedDB、REST 服务以及 Windows Azure,等等。 如果您要查看可用的数据选项,请参见我在 2013 年 3 月撰写的文章“Windows 应用商店应用程序中的数据访问和存储选项”(此文章位于 msdn.microsoft.com/magazine/jj991982)。

设置 Hub 控件的样式

在使用 JavaScript 生成的 Windows 应用商店应用程序中,您可以使用 CSS 来设置 Hub 控件的样式。 \hub\hub.css 文件包含与 Hub 控件相关的所有默认 CSS。 您可任意添加自己的样式以更改元素的大小及其布局。 图 4 显示了 hub.css 中的完整 CSS。 请注意,其中有一个 .hubpage 类选择器,它使用 HTML5 语义角色属性(如 header[role=banner] 和 section[role=main])来指定中心的一般样式。 此后,图 4 中的 CSS 会显示“.hubpage .hub .hero”子代选择器,此选择器将创建该 Hub 控件的特色 (hero) 节。 该 hero 用浅灰色背景填充屏幕可视部分左侧的大致一半,当然,这是在重要位置放置特殊内容的一个极佳方法! 您可在此处有效填充大量数据以及图形数据和多媒体作品以进行展示。

图 4 用于设置 Hub 控件的形状与样式的 CSS


  
  
  1.           .hubpage header[role=banner] {
  2.   position: relative;
  3.   z-index: 2;
  4. }
  5. .hubpage section[role=main] {
  6.   -ms-grid-row: 1;
  7.   -ms-grid-row-span: 2;
  8.   z-index: 1;
  9. }
  10. .hubpage .hub .win-hub-surface {
  11.   height: 100%;
  12. }
  13. .hubpage .hub .hero {
  14.   -ms-high-contrast-adjust: none;
  15.   background-image: url(/images/gray.png);
  16.   background-size: cover;
  17.   margin-left: -80px;
  18.   margin-right: 80px;
  19.   padding: 0;
  20.   width: 780px;
  21. }
  22.   .hubpage .hub .hero:-ms-lang(
  23.     ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab,
  24.      syr, ug, ur, qps-plocm) {
  25.     margin-left: 80px;
  26.     margin-right: -80px;
  27.   }
  28.   .hubpage .hub .hero .win-hub-section-header {
  29.     display: none;
  30.   }
  31.   .hubpage .hub .section1 {
  32.     width: 420px;
  33.   }
  34.   .hubpage .hub .section1 .win-hub-section-content {
  35.     overflow-y: hidden;
  36.   }
  37.   .hubpage .hub .section1 .subtext {
  38.     margin-bottom: 7px;
  39.     margin-top: 9px;
  40.   }
  41. .hubpage .hub .section2 {
  42.   width: 440px;
  43. }
  44.   .hubpage .hub .section2 .win-hub-section-content {
  45.     overflow-y: hidden;
  46.   }
  47.   .hubpage .hub .section2 .item-title {
  48.       margin-top: 4px;
  49.       margin-bottom: 10px;
  50.   }
  51.   .hubpage .hub .section2 .article-header {
  52.     margin-bottom: 15px;
  53.   }
  54. .hubpage .hub .section3 {
  55. }
  56.   .hubpage .hub .section3 .itemslist {
  57.     height: 100%;
  58.     margin-left: -10px;
  59.     margin-right: -10px;
  60.     margin-top: -5px;
  61.   }
  62.   .hubpage .hub .section3 .win-container {
  63.     margin-bottom: 36px;
  64.     margin-left: 10px;
  65.     margin-right: 10px;
  66.   }
  67.   .hubpage .hub .section3 .win-item {
  68.       height: 229px;
  69.       width: 310px;
  70.   }
  71.       .hubpage .hub .section3 .win-item img {
  72.         height: 150px;
  73.         margin-bottom: 10px;
  74.         width: 310px;
  75.       }
  76. .hubpage .hub .section4 {
  77.   width: 400px;
  78. }
  79.   .hubpage .hub .section4 .win-hub-section-content {
  80.         overflow-y: hidden;
  81.   }
  82.   .hubpage .hub .section4 .top-image-row {
  83.     height: 260px;
  84.     margin-bottom: 10px;
  85.     width: 400px;
  86.   }
  87.     .hubpage .hub .section4 .top-image-row img {
  88.       height: 100%;
  89.        width: 100%;
  90.     }
  91. .hubpage .hub .section4 .sub-image-row {
  92.   margin-bottom: 20px;
  93.   display: -ms-flexbox;
  94.   -ms-flex-flow: row nowrap;
  95.   -ms-flex-pack: justify;
  96. }
  97.   .hubpage .hub .section4 .sub-image-row img {
  98.     height: 95px;
  99.      width: 130px;
  100.   }
  101.         

您可以看到,图 4 中的 CSS 用于设置 Hub 控件的形状与样式,大部分内容涉及 HubSection 的布局和大小。 HubSection 内的元素和 WinJS 控件应用 ui-light.css 或 ui-dark.css 中的样式,除非您用自己的样式将这些样式覆盖。

HTML 应用程序依赖于 CSS 进行样式设置。 XAML 依赖于 XAML 进行样式设置。 这意味着 XAML 具有多种可应用于标记以实现样式定义的属性(称为资源)。 例如,对 TextBlock 设置样式的代码是 Style 属性,它引用一个名为 SubheaderTextBlockStyle 的内置(静态资源字典)样式:


          <TextBlock Style="{StaticResource SubheaderTextBlockStyle} />
        

页面的布局也是 XAML,因为所有 Hub、Grid 和其他元素都包含用于其屏幕位置及大小的内嵌坐标。 图 3 中您可以看到,具有用于定位元素(全部内嵌在 XAML 中)的边距、定位以及行和列设置。 HTML 最初是一种 Web 技术,通过使用 CSS(而不是 HTML)来节省带宽是它的一个实际优点。 在 XAML 中,所涉及的都是客户端,因此 UI 缓存不会有太大的问题,样式可以内嵌。 XAML 的优点是您需要做很少的事情就可确保快速响应的设计。 只需确保将两个 <RowDefinition> 元素的“Height”设置为“Auto”和“*”:


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

这些行将自动响应应用程序视图状态的变化,这会在避免额外代码同时使布局变得流畅。 图 3 显示了几个对自动高度调整行定义的引用。

可用的示例

在修改 Hub 控件、执行数据检索和绑定以及设置样式之后,一切都准备就绪了。 别忘了向您的应用程序增加一些时尚元素,如磁贴、搜索和其他 Windows 集成。 Hub 项目模板是在 HTML 或 XAML 中快速生成和发布应用程序的一种便捷方法。 通过使用 Hub 控件提供的中心导航模式,您可以生成遵循现代 UI 原则的高效和丰富的 UX。 您可在以下位置下载涵盖 Windows 应用程序开发诸多方面的 Hub 控件示例:

Rachel Appel 是一名顾问、作家、导师和前 Microsoft 员工,在 IT 行业有 20 多年的经验。她常在 Visual Studio Live!、DevConnections、MIX 等顶级行业大会上发言。她的专业是开发侧重于 Microsoft 系列开发技术和开放式 Web 并且符合业务和技术需要的解决方案。有关 Appel 的详细信息,请访问她的网站 rachelappel.com

衷心感谢以下技术专家对本文的审阅:Frank La Vigne (Microsoft)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值