65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Phone 7 的 Netflix 浏览器 - 第 1 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (57投票s)

2010年10月15日

CPOL

15分钟阅读

viewsIcon

230634

downloadIcon

1136

了解如何使用 Pivot 和 Panorama 控件、页面导航、OData 等!

我创建了一个应用程序视频

目录

引言

随着 Windows Phone 7 的热度不断攀升,以及 Daniel 撰写《Windows Phone 7 Unleashed》,我无法抗拒地加入了这一领域。毕竟,我提前看到了 Daniel 的书稿。所以我下载了工具并开始玩。我想探索 Panorama 和 Pivot 控件,并想出了一个使用 Netflix 数据、展示 Pivot 和 Panorama 控件以及 OData、页面导航、WrapPanel 等的精巧演示应用程序。本文将部分概述 Panorama 和 Pivot 控件,部分介绍演示应用程序的演练。

注意:在我撰写本文的过程中,页面数量不断增加,所以我将文章分成了两部分。 第二部分。

背景

最终的 Windows Phone 开发人员工具已经发布,随之而来的是,除其他外,官方发布了两个导航控件:Pivot 和 Panorama。这些控件对于 Windows Phone 上的视觉用户体验至关重要,并且手机内置应用程序广泛使用它们。因此,你无疑会发现自己经常使用它们。但这并不意味着它们适合所有应用程序。由于这些控件非常新且仅限于 Windows Phone(至少目前是这样),所以在理解它们时可能会有些困惑。有几种资源可用。特别有用的资源包括:由 Amy Alberts 和 Chad Roberts 主持的“Windows Phone Design Days – Pivot and Panos”视频,以及“Windows Phone 7 的 UI 设计和交互指南”。我将在下面的概述中参考这些资源。

在 Microsoft 官方发布这些控件之前,有一些替代方案,例如 Stephane Crozatier 在 Codeplex 上提供的 Panorama 和 Pivot 控件。对于那些使用这些早期控件构建应用程序的人来说,建议迁移到官方控件。幸运的是,Stephane Crozatier 撰写了一份迁移指南

将涵盖的内容

演示应用程序

演示应用程序是一个 Panorama 应用程序,允许用户浏览 Netflix 数据。在顶层,用户会看到一个包含流派、新发布和评分最高的电影的列表。然后,用户可以深入到每部电影以获取电影详细信息。从流派列表中选择一个流派将用户带到一个 Pivot,该 Pivot 列出了所选流派的电影;以三种不同的方式呈现数据:该流派的所有电影、按年份排序的电影以及按平均评分排序的电影。理想情况下,我希望看到所有流派的列表仅包含顶级流派,而不是长串的流派和子流派,但查询起来没有简单的方法。

前提条件

  • Windows Vista 或 Windows 7
  • Windows Phone 7 开发人员工具,其中包括 Visual Studio Express 2010 for Windows Phone、Windows Phone 模拟器、Expression Blend 4 for Windows Phone 和 XNA Game Studio 4.0
    • 如果尚未安装 Visual Studio Express 2010 和 Expression Blend 4,则会安装它们。
    • 如果您之前安装了 Beta 工具,则必须在安装最终工具之前将其卸载。请注意,安装可能需要一段时间。保持安装运行,它最终会完成。
  • Silverlight for Windows Phone Toolkit
  • OData Client Library for Windows Phone 7(当前可用的是 2010 年 3 月的版本)

理解 Pivot 和 Panorama 控件

Pivot 和 Panorama 是两个布局控件,它们可以帮助您以独特的方式在手机上呈现数据。它们有几个共同点。它们都包含多个水平排列的独立视图(部分)。它们在视觉上非常相似;都显示了屏幕外部分内容的一小部分,并带有标题和部分标题(参见图 1 和 2)。这两个控件都内置了触摸导航,允许用户使用平移和轻扫触摸手势在不同部分之间左右导航,当部分内容不适合屏幕边界高度时,则使用上下触摸手势。左右导航是循环的(即,最后一个部分之后是第一个部分)。

这些控件也非常不同。这主要是因为它们各自的目的不同。Panorama 旨在吸引用户探索;而 Pivot 则侧重于任务和完成某项工作。正如 Amy Alberts 和 Chad Roberts 在他们的演示中提到的,Pivot 是高效、专注、习惯性的,而 Panorama 是广泛的、动态的、鼓励探索的。我们可以从图 1 和 2 中看到这种区别,Panorama 提供了视觉吸引人的体验,通过吸引人的背景、大标题、各种 UI 控件、动画、缩略图等吸引用户,而 Pivot 看起来吸引力较低。它们的内容宽度也有一个区别。Panorama 视图通常跨越屏幕边界,而 Pivot 内容被限制在屏幕宽度内;适合屏幕。用户不仅可以通过左右手势在 Pivot 部分之间导航,还可以通过直接选择 Pivot 标题进行导航。

Panorama

Panorama 是一个宽大的水平画布,可以跨越屏幕边界。画布被切分成多个不同的视图,并使用分层动画和 UI 控件以不同方式表示数据,例如列表、网格、按钮等。出于可用性考虑,这些部分的数量应限制为四个,但每个部分的高度和宽度可以不同。Panorama 倾向于探索性,本质上作为多个其他体验的顶层。由于 Panorama 旨在吸引用户探索,它应该显示有趣且为用户量身定制的内容;它不应该感觉通用。我们也不希望用户感到被大量数据淹没。正如 Jeff Wilcox 所说:“Panorama 旨在成为起点,考虑留白而不是海量数据”。Panorama 包含数据和链接,这些链接将用户带到更详细的内容页面,例如 Pivot。然后,用户从 Panorama 的探索模式过渡到 Pivot 的更专注模式。

图 1:Panorama

正如您在图 1 中看到的,下一个部分的几个像素显示在右侧。这是为了提示用户 there is more content to explore。Panorama 应用程序应提供视觉吸引人的体验。这可以通过吸引人的背景来实现。它可以是纯色或背景图像。根据设计指南,图像的高度应为 800 像素,宽度为 480 至 1000 像素。图像的宽度可能更宽,但不能超过 2000 像素,因为图像将在此宽度处被裁剪。请注意,高度小于 800 像素的图像将按比例缩放至该高度,而不会约束比例。背景图像是 Panorama 的底层,不同的部分叠加在其之上。您不应尝试使背景依赖于内容,因为它们不会匹配。正如您在视频中看到的,Panorama 标题的移动速度与其部分标题的移动速度不同,因为用户在 Panorama 中移动。

Pivot

有些人认为 Pivot 与手机上的 TabControl 非常相似。Pivot 也有几个不同的视图(部分)。建议将部分数量限制为 7 个,以确保用户能够理解呈现给他们的内容。

与 Panorama 不同,Panorama 的内容可能会超出屏幕边界,而 Pivot 的内容被限制在屏幕宽度内。此外,与 Panorama 相反,Pivot 不显示下一个部分内容的几个像素,而是通过屏幕顶部的部分标题来指示数据如何过滤(参见图 2)。

图 2:Pivot

正如我们之前所说,Pivot 侧重于完成某项工作,因此 Pivot 适合拥有 ApplicationBar。这与 Panorama 应用程序不同,Panorama 应用程序不应显示 ApplicationBar。因此,如果您的页面需要应用程序栏,请使用 Pivot 而不是 Panorama。Pivot 设计用于表示相似类型的数据或项。例如,Pivot 可用作围绕同一任务流的相似内容的过滤器。电子邮件应用程序是一个很好的例子,它在一个视图中显示所有电子邮件,在另一个视图中显示已标记的电子邮件,在另一个视图中显示未读电子邮件,等等。

要避免的内容

您不应将 Pivot 放置在 Panorama 中,也不应嵌套 Pivot。您也不应尝试使用 Pivot 或 Panorama 来创建向导流程。正如 Amy Alberts 所说,用户将 Panorama 和 Pivot 视为呈现给他们的不同数据区域,而不是用户可以穿过的 UI 流程。因此,对于向导,请改用页面流程。还建议不要在 Pivot 或 Panorama 中使用地图控件。您还应避免为 Panorama 标题或部分标题设置动画,因为它们会随着用户在控件中移动而移动。还要避免动态更改 Panorama 标题。UI 指南还规定不要覆盖水平平移和轻扫功能,因为这会与控件的交互设计冲突。还要坚持推荐的视图数量,Pivot 为七个,Panorama 为四个。并记住,用户永远不应在 Panorama 中迷失方向,并且应始终知道如何返回。您也不会希望 Panorama 中的每个链接都带您到一个 Pivot。

演示应用程序:入门

这两个控件都有自定义模板,您可以使用它们来创建 Pivot 或 Panorama。您可以创建一个新的 Pivot 或 Panorama 应用程序项目,或者对于现有项目,您可以添加一个新的 Pivot 或 Panorama 页面。我们将演示这两种方法。这两个控件也可以通过 Visual Studio 添加到工具箱中,然后拖到页面上。

我们首先创建一个新的 Panorama 应用程序项目。在 Visual Studio 中,转到“文件”->“新建”->“项目”,然后在“Silverlight for Windows Phone”选项下选择“Windows Phone Panorama Application”(参见图 3)。

图 3:创建新的 Windows Phone Panorama 应用程序

项目创建后,我们可以看到模板为我们提供了项目结构、一些示例数据以及 Panorama 的格式化视图。Visual Studio 还提供了一个方便的功能,可以在设计器中查看 panorama 部分。设计器将显示当前选定的 panorama 项的 xaml(参见图 4)。

图 4:Visual Studio 设计器中的 Panorama。

Phone 应用程序模板还附带以下默认图像:

  • 应用程序图标 (ApplicationIcon.png)
    • 应用程序图标用于快速启动屏幕。
  • 应用程序磁贴的背景图像 (background.png)
    • 当用户将应用程序固定到开始屏幕后,应用程序磁贴会显示在开始体验中,用于快速启动。您可以通过在模拟器中按快速启动屏幕上的应用程序图标来将应用程序固定到开始体验。一两秒后,您应该会看到一个上下文菜单,其中包含固定到开始或卸载的选项(参见图 6)。您可以在应用程序属性中设置磁贴标题和背景图像,如图 5 所示。您将能够通过磁贴通知更改磁贴标题、其背景图像和计数器,以创建个性化的用户体验,但这超出了本文的范围。
  • 启动屏幕 (SplashScreenImage.jpg)
    • 在应用程序加载到第一个页面之前,会显示启动屏幕。创建启动屏幕有一些规则,例如图像的宽度和高度必须为 480 x 800 像素,图像名称必须为 SplashScreenImage.jpg,并且“生成操作”属性必须设置为 Content

图 5:设置应用程序标题、图标、磁贴标题和磁贴背景图像

图 6:将应用程序固定到开始屏幕

Panorama 控件

使用 Panorama 控件非常简单。下面摘录的代码来自 Panorama 应用程序模板。我们可以看到,Panorama 控件包含两个 PanoramaItem 内容控件。PanoramaItem 控件承载全景内容,这些是我们在上面概述中讨论的视图或部分。根据建议,Panorama 控件中不应有超过四个 PanoramaItem 控件。在演示中,我们使用了三个。虽然我们在演示中没有使用它,但 PanoramaItem 控件可以在运行时以编程方式添加和删除。Panorama 控件包含 TitleBackground 属性。下面摘录中的 Title 指定为文本,但它有一个 TitleTemplate 依赖属性,因此也可以通过数据绑定设置。这同样适用于 PanoramaItemHeader 属性。正如下面所见,全景背景以 ImageBrush 的形式作为图像应用,我们在演示中也使用了相同的图像,但您也可以使用 GradientBrushSolidColorBrush。如果您使用背景图像,则其“生成操作”应设置为 Resource,以确保它在应用程序的第一个页面启动时显示。将“生成操作”设置为 Content 意味着它被异步加载。请注意下面摘录中的所有 panorama 项的左右边距都设置为 12px。出于用户体验原因,这同样适用于 Pivot 控件。

<!--Panorama control-->
<controls:Panorama Title="my application">
  <controls:Panorama.Background>
    <ImageBrush ImageSource="PanoramaBackground.png"/>
  </controls:Panorama.Background>

  <!--Panorama item one-->
  <controls:PanoramaItem Header="first item">
    <!--Double line list with text wrapping-->
    <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Margin="0,0,0,17" Width="432">
            <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" 
                Style="{StaticResource PhoneTextExtraLargeStyle}"/>
            <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" 
                Margin="12,-6,12,0" 
                Style="{StaticResource PhoneTextSubtleStyle}"/>
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </controls:PanoramaItem>

  <!--Panorama item two-->
  <!--Use 'Orientation="Horizontal"' 
         to enable a panel that lays out horizontally-->
  <controls:PanoramaItem Header="second item">
    <!--Double line list with image placeholder and text wrapping-->
    <ListBox Margin="0,0,-12,0" ItemsSource="{Binding Items}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal" Margin="0,0,0,17">
            <!--Replace rectangle with image-->
            <Rectangle Height="100" Width="100" Fill="#FFE5001b" 
                Margin="12,0,9,0"/>
            <StackPanel Width="311">                                    
              <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" 
                Style="{StaticResource PhoneTextExtraLargeStyle}"/>
              <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" 
                Margin="12,-6,12,0" 
                Style="{StaticResource PhoneTextSubtleStyle}"/>
            </StackPanel>
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </controls:PanoramaItem>
</controls:Panorama>

对于演示应用程序,我修改了示例 Panorama 控件。我更改了 Panorama 的背景和标题,修改了 PanoramaItem 布局,设置了 PanoramaItem 的标题,并替换了绑定表达式。我还定义了一个新的 PanoramaForegroundBrushPanorama 模板中使用的 TextBox Foreground 样式为手机的深色和浅色主题提供了自动支持。行为是:在深色主题下,Panorama 中的文本为白色,在浅色主题下变为黑色。黑色文本与 Panorama 背景不匹配,因此我定义了一个新的 PanoramaForegroundBrush,并将 Panorama 控件中每个 TextBlockForeground 属性设置为新笔刷。

<UserControl.Resources>
	<SolidColorBrush x:Key="PanoramaForegroundBrush" Color="#FFf6f0d9"/>
</UserControl.Resources>

第一个 Panorama 部分显示所有流派的列表。我们将部分 Header 设置为 'genres',并使用 ListBox 控件允许用户垂直浏览列表(见下文)。

<!--Panorama item one-->
<controls:PanoramaItem Header="genres" >
  <ListBox x:Name="GenreListBox"  Margin="0,0,-12,0" 
       ItemsSource="{Binding Genres}" 
       SelectionChanged="GenreListBoxSelectionChanged">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Margin="0,0,0,17" Width="432">
          <TextBlock Text="{Binding Name}" TextWrapping="Wrap" 
                 Foreground="{StaticResource PanoramaForegroundBrush}" 
                 Style="{StaticResource PhoneTextLargeStyle}"/>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</controls:PanoramaItem>

第二个 Panorama 部分显示新发布。信息以小型电影缩略图、标题、平均评分和 DVD 可用日期的方式呈现。同样,我们设置了 Header 并使用 ListBox 控件来布局内容(见下文)。

<!--Panorama item two-->
<controls:PanoramaItem Header="new releases" >
  <ListBox Margin="0,0,-12,0" x:Name="NewTitlesListBox" 
       ItemsSource="{Binding NewTitles}" 
       SelectionChanged="TitlesListBoxSelectionChanged">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal" Margin="0,0,0,20">
          <Image  CacheMode="BitmapCache" Source="{Binding BoxArt.LargeUrl}" 
              Margin="12,0,9,0"/>
          <StackPanel Width="311">
            <TextBlock Text="{Binding Name}" TextWrapping="Wrap"  
                   Foreground="{StaticResource PanoramaForegroundBrush}" 
                   Style="{StaticResource PhoneTextLargeStyle}"/>
            <StackPanel Orientation="Horizontal" >
              <TextBlock  Margin="12,5,5,5" Text="Rating:" 
                    Foreground="{StaticResource PanoramaForegroundBrush}" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
              <TextBlock  Margin="0,5,0,5" Text="{Binding AverageRating}" 
                    Foreground="{StaticResource PanoramaForegroundBrush}" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
              <TextBlock  Margin="12,5,5,20" Text="Available: " 
                    Foreground="{StaticResource PanoramaForegroundBrush}" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
              <TextBlock Margin="0,5,0,20" Text="{Binding Dvd.AvailableFrom, 
                     Converter={StaticResource StringFormatConverter},
                      ConverterParameter=\{0:d MMMM yyyy\}}" 
                     TextWrapping="Wrap" 
                     Foreground="{StaticResource PanoramaForegroundBrush}" 
                     Style="{StaticResource PhoneTextNormalStyle}"/>
            </StackPanel>
          </StackPanel>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</controls:PanoramaItem

字符串格式转换器

在第二个 PanoramaItem 中,有一个日期字段需要格式化。在 Silverlight 4 中,您可以在 Binding 表达式中直接指定 string 格式,但由于 Windows Phone 基于 Silverlight 3,我们需要使用 Converter。幸运的是,Daniel 以前写过这样一个转换器,所以我将他的 StringFormatConverter 类整合到了我的演示中。谢谢亲爱的。要使用 StringFormatConverter 类,请在 MainPage.xaml 中添加一个 namespace 引用,如下所示:

xmlns:converter="clr-namespace:NetflixBrowser.Helpers"

如下所示,将转换器添加为资源:

<UserControl.Resources>
	<converter:StringFormatConverter x:Key="StringFormatConverter" />
</UserControl.Resources>

指定 ConverterParameter 属性来定义格式:

<TextBlock Margin="0,5,0,20" Text="{Binding Dvd.AvailableFrom, 
	Converter={StaticResource StringFormatConverter}, 
	ConverterParameter=\{0:d MMMM yyyy\}}" 
	TextWrapping="Wrap" 
	Foreground="{StaticResource PanoramaForegroundBrush}" 
	Style="{StaticResource PhoneTextNormalStyle}"/>

Pivot 控件

我们将 Pivot 控件添加为一个新的 Pivot 页面。在“解决方案资源管理器”中,右键单击项目,然后转到“添加”->“新项”,并选择“Windows Phone Pivot Page”(参见图 7)。

图 7:添加新的 Windows Phone Pivot 页面

以下摘录显示了 pivot 控件模板。我们可以看到与 Panorama 控件有许多相似之处。与 Panorama 控件一样,Pivot 控件包含 PivotItem 内容控件。它有一个 Title 和一个 BackgroundTitle 可以设置为文本,也可以像 Panorama 控件一样进行 数据绑定。同样,这对于 PivotItem 的标题也适用。Pivot 的背景也可以设置为图像。我们在演示应用程序中不设置 Pivot Background 属性,因此 Pivot 的背景会根据手机上设置的深色或浅色主题(这意味着它是黑色或白色)进行显示。

<!--Pivot Control-->
<controls:Pivot Title="MY APPLICATION">
	<!--Pivot item one-->
	<controls:PivotItem Header="item1">
	  <Grid/>
	</controls:PivotItem>

	<!--Pivot item two-->
	<controls:PivotItem Header="item2">
	  <Grid/>
	</controls:PivotItem>
</controls:Pivot>

在演示应用程序中,我们使用 Pivot 控件来显示所选流派的电影。Pivot 页面称为 GenreDvds.xaml。与 Panorama 控件一样,我修改了模板,更改了 Pivot 标题、标题等。由于 GenreDvds.xml 页面是从 Panorama 页面导航过来的,显示所选流派的 DVD,因此我使用 Binding 表达式设置了 Pivot 标题,如下所示:

<!--Pivot Control-->
<controls:Pivot  x:Name="SelectedGenre" Title="{Binding SelectedGenreName}" 
	Visibility="{Binding Loaded, 
         Converter={StaticResource BooleanToVisibilityConverter}, 
	ConverterParameter=Visible}">
	.
	.
	.
</controls:PivotItem>

在上面的摘录中,您还可以看到我们正在动态设置 Pivot 的可见性。这将在本文的第二部分“进度条”部分进行介绍。

Pivot 控件有三个部分。所有三个部分都以相同的方式布局,显示电影缩略图、标题、简短的简介、平均评分和可用性。

<!--Pivot item one-->
<controls:PivotItem Header="all">
  <ListBox Margin="0,0,-12,0" ItemsSource="{Binding GenreTitles}">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal" Margin="0,0,0,20">
          <Image  CacheMode="BitmapCache" Source="{Binding BoxArt.LargeUrl}" 
            Margin="12,0,9,0"/>
          <StackPanel Width="311">
            <TextBlock Text="{Binding Name}" TextWrapping="Wrap" 
                   Style="{StaticResource PhoneTextLargeStyle}"/>
            <TextBlock Text="{Binding ShortSynopsis}" TextWrapping="Wrap" 
                Margin="12,-6,12,10" 
                   Style="{StaticResource PhoneTextSubtleStyle}"/>            
            <StackPanel Orientation="Horizontal" >
              <TextBlock  Margin="12,5,5,5" Text="Rating:" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
              <TextBlock  Margin="0,5,0,5" Text="{Binding AverageRating}" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
              <TextBlock  Margin="12,5,5,20" Text="Available: " 
                Style="{StaticResource PhoneTextNormalStyle}"/>
              <TextBlock Margin="0,5,0,20" 
                     Text="{Binding Dvd.AvailableFrom, 
                    Converter={StaticResource StringFormatConverter}, 
                     ConverterParameter=\{0:d MMMM yyyy\}}" 
                     TextWrapping="Wrap" 
                   Style="{StaticResource PhoneTextNormalStyle}"/>
            </StackPanel>
          </StackPanel>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</controls:PivotItem>>

结论

在本文中,我们探讨了 PivotPanorama 控件,介绍了演示应用程序,了解了如何将控件添加到项目中,并查看了 PivotPanorama 模板。在本文的第二部分,我们将介绍 ODataWrapPanel、页面导航和进度条。我希望您发现本文有用。如果您喜欢我的文章,请评价它,并在下方分享您的想法。

历史记录

  • 2010 年 10 月:首次发布

参考文献

© . All rights reserved.