从 Windows Phone Silverlight 移植到 UWP 案例研究:Bookstore1

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

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

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

注意 在 Visual Studio 中打开 Bookstore1Universal_10 时,如果你看到消息“需要 Visual Studio 更新”,则按照 TargetPlatformVersion 中用于设置目标平台版本的步骤进行操作。

下载

下载 Bookstore1WPSL8 Windows Phone Silverlight 应用

下载 Bookstore1Universal_10 Windows 10 应用

Windows Phone Silverlight 应用

Bookstore1WPSL8(我们将移植的应用)的外观如下。 它只是一个垂直滚动的书籍列表框,位于应用名称和页面标题下。

Bookstore1WPSL8 的外观

移植到 Windows 10 项目

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

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

我们可以将 Visual Studio 生成的 App.xaml 和 App.xaml.cs 保存在 Windows 10 项目中。

编辑你刚刚复制的源代码和标记文件,并将对 Bookstore1WPSL8 命名空间的任何引用更改为 Bookstore1Universal_10。 执行此操作的快速方法是使用“在文件中替换”功能。 在视图模型源文件的强制性代码中,需要进行以下移植更改:

  • 将 更改为 System.ComponentModel.DesignerPropertiesDesignMode ,然后对它使用 Resolve 命令。 删除 IsInDesignTool 属性并使用 IntelliSense 添加正确的属性名称:DesignModeEnabled
  • ImageSource 使用 Resolve 命令。
  • BitmapImage 使用 Resolve 命令。
  • 使用 System.Windows.Media;using System.Windows.Media.Imaging; 删除。
  • 将 Bookstore1Universal_10.BookstoreViewModel.AppName 属性返回的值从“BOOKSTORE1WPSL8”更改为“BOOKSTORE1UNIVERSAL”。

在 MainPage.xaml 中,需要进行以下移植更改:

  • phone:PhoneApplicationPage 更改为 Page(不要忘记出现在属性元素语法中的相应项)。
  • 删除 phoneshell 命名空间前缀声明。
  • 在其余的命名空间前缀声明中将“clr-namespace”更改为“using”。

如果我们要尽快看到结果,可以选择经济地更正标记编译错误,即使这意味着临时删除标记。 但是,让我们保留通过执行此操作获取的债务记录。 它在此情况下如下所示。

  1. MainPage.xaml 的根 Page 元素中,删除 SupportedOrientations="Portrait"
  2. MainPage.xaml 的根 Page 元素中,删除 Orientation="Portrait"
  3. MainPage.xaml 的根 Page 元素中,删除 shell:SystemTray.IsVisible="True"
  4. 在数据模板中BookTemplate,删除对 和 PhoneTextSubtleStyleTextBlock 样式的PhoneTextExtraLargeStyle引用。
  5. TitlePanelStackPanel 中,删除对 和 PhoneTextTitle1StyleTextBlock 样式的PhoneTextNormalStyle引用。

让我们先使用适用于移动设备系列的 UI,在这之后我们可以考虑其他外形规格。 现在,你可以生成并运行该应用。 下面是它在移动仿真器上所呈现的外观。

移动设备上初始源代码发生更改的 UWP 应用

视图和视图模型正确地协同工作,并且 ListBox 处于运行状态。 我们通常只需修复样式设置并使图像显示。

支付债务项和一些初始样式设置

默认情况下,支持所有方向。 但是,Windows Phone Silverlight 应用将自身明确约束为仅限纵向,因此债务项 #1 和 #2 通过转到新项目中的应用包清单中并选中“支持的方向”下的“纵向”来支付。

对于此应用,项 #3 不是债务,因为默认情况下会显示状态栏(以前称为系统托盘)。 对于项 #4 和 #5,我们需要找到与已在使用的 Windows Phone Silverlight 样式相对应的四个通用 Windows 平台 (UWP) TextBlock 样式。 可以在仿真器中运行 Windows Phone Silverlight 应用并将其与文本部分中的图示并排比较。 通过执行该操作以及查看 Windows Phone Silverlight 系统样式的属性,我们可以生成此表。

Windows Phone Silverlight 样式键 UWP 样式键
PhoneTextExtraLargeStyle TitleTextBlockStyle
PhoneTextSubtleStyle SubtitleTextBlockStyle
PhoneTextNormalStyle CaptionTextBlockStyle
PhoneTextTitle1Style HeaderTextBlockStyle

若要设置这些样式,你可以将它们键入标记编辑器,或者可以使用 Visual Studio XAML 工具设置它们,无需键入任何内容。 若要执行该操作,请右键单击“TextBlock”,然后单击“编辑样式”>“应用资源”。 若要对项模板中的 TextBlock 执行该操作,请右键单击“ListBox”,然后依次单击“编辑其他模板”>“编辑生成的项(ItemTemplate)”。

项目后有一个 80% 不透明的白色背景,因为 ListBox 控件的默认样式将其背景设置为 ListBoxBackgroundThemeBrush 系统资源。 在 ListBox 上设置Background="Transparent"以清除该背景。 若要使项模板中的 TextBlock 向左对齐,请采用上述的相同方式再次编辑它,并在两个 TextBlock 上都设置 "9.6,0"Margin

完成该操作后,由于更改与视图像素有关,因此我们需要检查尚未更改的大小维度(边距、宽度、高度等)并将其乘以 0.8。 例如,因此图像应该从 70x70px 更改为 56x56px。

但是,让我们在显示样式设置的结果前获取要呈现的图像。

将图像绑定到视图模型

在 Bookstore1WPSL8 中,我们执行了以下操作:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));

在 Bookstore1Universal 中,我们使用 ms-appx URI 方案。 因此,我们可以使其余的代码保持原样,可以使用 System.Uri 构造函数的不同重载将 ms-appx URI 方案放在基 URI 中,并在其中追加路径的其余部分。 如:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(new Uri("ms-appx://"), this.CoverImagePath));

通用样式设置

现在,我们只需要进行一些最终样式设置的调整,并确认应用在桌面设备(和其他)外形规格以及移动设备上外观良好。 具体步骤如下。 并且你可以使用本主题顶部的链接下载这些项目,并查看此处和案例研究末尾之间的所有更改结果。

  • 若要收紧项之间的间距, BookTemplate 请在 MainPage.xaml 中找到数据模板, Margin 并从根 网格中删除 属性。
  • 如果要给页面标题多一点喘息空间,可以在页面标题 TextBlock 上将 的下边距-5.6重置为 0
  • 现在,我们需要将 LayoutRoot 的 Background 设置为正确的默认值,以便无论使用何种主题,应用在所有设备上运行时都具有合适的外观。 将其从 "Transparent" 更改为 "{ThemeResource ApplicationPageBackgroundThemeBrush}"

对于较复杂的应用,这将是我们使用针对外形规格和用户体验进行移植中的指南的原因,并且真正充分利用现在可运行此类应用的每一种设备外形规格。 但对于此简单应用,我们可以在此处停止操作,并查看该应用在样式设置操作的最后一步中的外观。 实际上,该应用在移动设备和桌面设备上的外观均相同,尽管它并未充分利用较宽的外形规格上的空间(不过,我们将在以后的案例研究中调查如何实现该目的)。

请参阅主题更改以查看如何控制你的应用的主题。

已移植的 Windows 10 应用

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

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

当应用在移动设备上运行时,列表框的背景在两种主题下都默认为浅色。 这可能是你喜欢的样式,如果是,则无需执行其他任何操作。 但控件的设计目的是你可以自定义它们的外观,同时使其行为不受影响。 因此,如果你希望列表框在深色主题下显示为深色(这是原始应用的外观),请按照“可选调整”下的这些说明操作。

结束语

此案例研究介绍了移植非常简单的应用(可以认为是一个过分简单的应用)的过程。 例如,列表控件可用于选择或者用于建立导航的上下文;应用导航到具有有关所点击的项的更多详细信息的页面。 根据用户的选择,此特定应用不执行任何操作,并且它没有导航。 即便如此,案例研究仍可用于打破僵局、介绍移植过程以及演示可在真实的 UWP 应用中使用的重要技术。

下一个案例研究是 Bookstore2,我们将从中了解访问和显示分组数据。