Windows 运行时 8.x 到 UWP 案例研究:Bookstore1

本主题介绍将非常简单的通用 8.1 应用移植到 Windows 10 通用 Windows 平台 (UWP) 应用的案例研究。 通用 8.1 应用是为 Windows 8.1 生成一个应用包,另一个适用于 Windows Phone 8.1 的应用包。 在 Windows 10 中,你可以创建可供客户安装到种类广泛的设备上的单个应用包,而这正是我们要在此案例研究中实现的目标。 请参阅 UWP 应用的指南。

我们将移植的应用由绑定到视图模型的 ListBox 组成。 视图模型包含显示标题、作者和书籍封面的书籍列表。 书籍封面已将“生成操作”设置为“内容”,并将“复制到输出目录”设置为“不要复制”

本节前面的主题介绍了平台之间的差异,它们通过绑定到视图模型,提供有关从 XAML 标记到视图模型到访问数据的应用的各个方面的移植过程的详细信息和指导。 案例研究旨在通过在实际示例中展示指导来补充该指导。 案例研究假设你已阅读指南,这些指南不会重复。

注意 在 Visual Studio 中打开 Bookstore1Universal_10 时,如果看到消息“需要 Visual Studio 更新”,则请按照 TargetPlatformVersion 中的步骤进行操作。

下载

下载 Bookstore1_81 通用 8.1 应用

下载 Bookstore1Universal_10 Windows 10 应用

通用 8.1 应用

Bookstore1_81(我们将移植的应用)的外观如下。 它只是应用名称和页面标题标题下方的垂直滚动列表框。

bookstore1-81 在窗口上的外观

Windows 上的 Bookstore1_81

bookstore1-81 在 Windows Phone 上的外观

Windows Phone 上的 Bookstore1_81

移植到 Windows 10 项目

Bookstore1_81 解决方案是 8.1 通用应用项目,它包含以下项目。

  • Bookstore1_81.Windows。 这是为 Windows 8.1 生成应用包的项目。
  • Bookstore1_81.WindowsPhone。 这是为 Windows Phone 8.1 生成应用包的项目。
  • Bookstore1_81.Shared。 这是包含其他两个项目使用的源代码、标记文件和其他资产和资源的项目。

对于此案例研究,我们有一些常见选项, 如你有一个通用 8.1 应用 ,说明要支持哪些设备。 此处的决定很简单:此应用具有相同的功能,并且主要使用相同代码(在 Windows 8.1 和 Windows Phone 8.1 窗体中)。 因此,我们将共享项目的内容(以及我们需要的其他任何项目)移植到面向通用设备系列的 Windows 10(可以安装到最广泛的设备上)。

可快速完成以下任务:在 Visual Studio 中创建新项目、将文件从 Bookstore1_81 复制到其中并将已复制的文件包含在新项目中。 首先创建新的空白应用程序(Windows 通用)项目。 将它命名为 Bookstore1Universal_10。 这些是要从 Bookstore1_81 复制到 Bookstore1Universal_10 的文件。

从共享项目

  • 复制包含书籍封面图像 PNG 文件的文件夹(该文件夹是 \Assets\CoverImages)。 复制文件夹后,在解决方案资源管理器中,确保打开“显示所有文件”。 右键单击你复制的文件夹,然后单击“包括在项目中”。 此命令是指在项目中“包括”文件或文件夹。 每次你复制文件或文件夹、每个副本时,请在“解决方案资源管理器”中单击“刷新”,然后将文件或文件夹包括在项目中。 对于目标中要替换的文件,无需执行此操作。
  • 复制包含视图模型源文件的文件夹(该文件夹是 \ViewModel)。
  • 复制 MainPage.xaml 并替换目标中的文件。

从 Windows 项目

  • 复制 BookstoreStyles.xaml。 我们将使用此密钥作为良好的起点,因为此文件中的所有资源密钥都将在 Windows 10 应用中解析;等效的 WindowsPhone 文件中的一些内容不会。

编辑你刚刚复制的源代码和标记文件,并将对 Bookstore1_81 命名空间的任何引用更改为 Bookstore1Universal_10。 执行此操作的快速方法是使用“在文件中替换”功能。 视图模型中不需要代码更改,也不需要任何其他命令性代码。 但为了更易于查看应用正在运行哪个版本,请将 Bookstore1Universal_10.BookstoreViewModel.AppName 属性返回的值从“BOOKSTORE1_81”更改为“BOOKSTORE1UNIVERSAL_10”

现在,可以生成并运行。 下面是新 UWP 应用在尚未完成显式工作后如何将其移植到 Windows 10。

没有显式更改的 Windows 10 应用的屏幕截图。

在桌面设备上运行的初始源代码更改的 Windows 10 应用

Windows 10 应用的屏幕截图,其中包含初始源代码更改。

在移动设备上运行的初始源代码更改的 Windows 10 应用

视图和视图模型正常工作, ListBox 正常运行。 我们只需要修复样式设置。 在移动设备上,在浅色主题中,可以看到列表框的边框,但这很容易隐藏。 而且,版式太大,因此我们将更改所使用的样式。 此外,如果希望应用看起来像默认值,则应用在桌面设备上运行时应为浅色。 因此,我们将改变这一点。

通用样式

Bookstore1_81 应用使用了两个不同的资源词典 (BookstoreStyles.xaml) 来为 Windows 8.1 和 Windows Phone 8.1 操作系统定制其样式。 这两个 BookstoreStyles.xaml 文件都不包含 Windows 10 应用所需的样式。 但是,好消息是,我们希望的东西实际上比其中任何一个都简单得多。 因此,后续步骤主要涉及删除和简化项目文件和标记。 以下步骤如下。 可以使用本主题顶部的链接下载项目,并查看此处和案例研究末尾之间所有更改的结果。

  • 若要收紧项之间的间距,请查找 BookTemplate MainPage.xaml 中的数据模板,并从根网格中删除Margin="0,0,0,8"数据模板
  • 此外,还有 BookTemplateBookTemplateTitleTextBlockStyleBookTemplateAuthorTextBlockStyle的引用。 Bookstore1_81 将这些键用作了间接寻址,因此单个键在这两个应用中具有不同的实现。 我们不再需要这种间接性;我们可以直接引用系统样式。 因此,请将这些引用分别替换为 TitleTextBlockStyleSubtitleTextBlockStyle
  • 现在,我们需要将“背景”设置为 LayoutRoot正确的默认值,以便在所有设备上运行时应用看起来合适,无论主题是什么。 将其从 "Transparent" 更改为 "{ThemeResource ApplicationPageBackgroundThemeBrush}"
  • TitlePanel,将引用 TitleTextBlockStyle (现在太大)更改为引用 CaptionTextBlockStylePageTitleTextBlockStyle 是另一个我们不再需要的 Bookstore1_81 间接寻址。 请改为更改它以引用 HeaderTextBlockStyle
  • 我们不再需要在 ListBox设置任何特殊的 Background、Style 和 ItemContainerStyle,因此只需从标记中删除这三个属性及其值即可。 不过,我们确实想要隐藏 ListBox边框,因此请将其添加到BorderBrush="{x:Null}"其中。
  • 我们不再引用 BookstoreStyles.xaml ResourceDictionary 文件中的任何资源。 可以删除所有这些资源。 但是,请勿删除 BookstoreStyles.xaml 文件本身:我们仍具有最后一个用途,如下一部分所示。

最后一系列样式设置操作使应用看起来如下所示。

具有最后一系列样式操作的应用的屏幕截图。

在桌面设备上运行的几乎移植的 Windows 10 应用

已移植的 Windows 10 应用的屏幕截图。

在移动设备上运行的几乎移植的 Windows 10 应用

移动设备列表框的可选调整

当应用在移动设备上运行时,列表框的背景在两个主题中默认为浅色。 这可能是你喜欢的样式,如果是这样,除了整理之外,别无其他操作:从项目中删除 BookstoreStyles.xaml 资源字典文件,并删除将其合并到 MainPage.xaml 中的标记。

但是,控件的设计是为了让你在离开其行为不受影响的同时自定义其外观。 因此,如果希望列表框在深色主题中为深色(原始应用的外观),则本部分介绍一种执行此操作的方法。

在移动设备上运行时,我们所做的更改只需要影响应用。 因此,当我们在移动设备系列上运行时,我们将使用非常轻微的自定义列表框样式,当我们在其他地方运行时,我们将继续使用默认样式。 为此,我们将创建 BookstoreStyles.xaml 的副本,并为它提供一个特殊的 MRT 限定名称,这将导致它仅在移动设备上加载。

添加新的 ResourceDictionary 项目项并将其命名为 BookstoreStyles.DeviceFamily-Mobile.xaml。 你现在有两个文件,其逻辑名称是 BookstoreStyles.xaml(这就是在标记和代码中使用的名称)。 不过,这些文件具有不同的物理名称,因此可以包含不同的标记。 可以将此 MRT 限定命名方案用于任何 xaml 文件,但请注意,具有相同逻辑名称的所有 xaml 文件共享单个xaml.cs代码隐藏文件(其中一个适用)。

编辑列表框的控件模板的副本,并使用新资源字典 BookstoreStyles.DeviceFamily-Mobile.xaml 中的密钥 BookstoreListBoxStyle 存储该模板。 现在,我们将对三个资源库进行简单的更改。

  • 在前台设置器中,将值更改为 "{x:Null}"。 请注意,将属性设置为 "{x:Null}" 直接在元素上与在代码中设置属性 null 相同。 但是,在 setter 中使用值 "{x:Null}" 具有唯一的效果:它重写默认样式中的 setter(对于同一属性),并还原目标元素上的属性的默认值。
  • 在 Background setter 中,将值更改为 "Transparent" 删除该浅色背景。
  • 在模板设置器中,找到命名 Focused 并删除其情节提要的视觉状态,使其成为空标记。
  • 从标记中删除所有其他资源库。

最后,复制到 BookstoreListBoxStyle BookstoreStyles.xaml 并删除其三个 setter,使其成为空标记。 为此,在移动设备以外的设备上,我们对 BookstoreStyles.xaml 的引用将 BookstoreListBoxStyle 得到解决,但不起作用。

移植的 Windows 10 应用

在移动设备上运行的已移植的 Windows 10 应用

结束语

此案例研究显示了移植非常简单的应用的过程,可以说是一个不切实际的简单应用。 例如,列表框可用于选择或建立导航上下文;该应用导航到一个页面,其中包含有关已点击的项目的更多详细信息。 此特定应用不执行用户选择,并且没有导航。 即便如此,案例研究也有助于打破冰层,引入移植过程,并演示可在实际 UWP 应用中使用的重要技术。

我们还看到了移植视图模型通常是一个流畅的过程的证据。 用户界面和外形规格支持是移植时更可能需要注意的方面。

下一个案例研究是 Bookstore2,我们将在其中查看访问和显示分组数据。