Windows 10 开发 – 快速指南
Windows 10 开发 – 快速指南
Windows 10 开发 – 简介
本教程专为想要学习如何开发 Windows 10 应用程序的人而设计。在本教程中,我们将学习 –
- Windows 10 应用程序开发
- 微软发布的新操作系统的更新
- 更新中为开发人员提供的新功能
许多有趣的应用程序场景现在可能是我们在第一个版本中不可用的。Microsoft 不仅添加了新的 API,还扩展了现有的 API。
通用 Windows 应用程序
通用 Windows 应用程序首先作为 Windows 运行时在 Windows 8 中引入,它构建在通用应用程序平台上。
现在,在 Windows 10 中,通用应用程序平台的名称已更改为通用 Windows 平台 (UWP)。您可以通过面向 Windows 应用商店的 Windows 10 设备(例如 PC、平板电脑、手机等)构建现代且完全身临其境的应用程序。
在 Windows 10 中,您可以轻松开发应用程序以访问 Windows 10 支持的所有设备,只需 –
- 一套 API
- 一个应用程序包
- 还有一家店
通用 Windows 平台还支持不同的屏幕尺寸和不同的交互模型,例如触摸板、鼠标和键盘、游戏控制器或笔。
UWP 应用的特点
以下是通用 Windows 应用程序的一些特性,使其优于 Windows 10。
-
您可以定位设备系列,而不是像 Windows 8.1 这样的操作系统。
-
应用程序使用.AppX打包格式进行打包和分发,可确保您的应用程序可以无缝部署和更新。
-
您可以将您的应用程序提交到 Windows 商店,它将在所有设备系列或仅您选择的设备上提供。您可以在一个位置轻松管理适用于 Windows 设备的所有应用程序。
-
您可以将应用程序的可用性限制为特定设备系列。
-
通用 Windows 平台 (UWP) 的核心 API 在所有 Windows 设备系列中都是相同的。因此,如果您的应用仅使用核心 API,则它可以在所有 Windows 10 设备上运行。
-
在扩展 SDK 的帮助下,您可以为特定设备点亮您的应用程序。
发展选择
可以使用以下任何一种语言创建通用 Windows 应用程序 –
- 带有 XAML 的 C# 或 Visual Basic
- 带有 HTML 的 JavaScript
- 带有 DirectX 和/或 XAML 的 C++
您还可以用一种语言编写组件并在用另一种语言开发的应用程序中使用它们。
Windows 10 开发 – UWP
Windows 运行时 (WinRT) 是一种平台同构的应用程序架构,支持在 C++/CX、C#、VB.NET 和 JavaScript 中进行开发。WinRT 应用程序本身支持 x86 和 ARM 架构。一些重要的功能是。
-
它于 2012 年 9 月首次在 Windows Server 2012 中引入。
-
WinRT API 提供对使用 JavaScript、C#、Visual Basic 和 C++ 的所有核心平台功能的访问。
-
WinRT 组件支持多种语言和 API,例如本机、托管和脚本语言。
通用 Windows 平台 (UWP)
通用 Windows 应用基于通用 Windows 平台 (UWP) 构建,该平台最初作为 Windows 运行时在 Windows 8 中引入。在 Windows 10 中,引入了通用 Windows 平台 (UWP),这进一步推进了 Windows 运行时 (WinRT) 模型。
-
在 Windows 8.1 中,WinRT 首次在 Windows Phone 8.1 应用程序和 Windows 8.1 应用程序之间在通用 Windows 8 应用程序的帮助下对齐,以使用共享代码库同时针对 Windows Phone 和 Windows 应用程序。
-
Windows 10 统一核心(现在称为 Windows 核心)已经达到了这样一个程度,即 UWP 现在提供了一个通用应用平台,可用于在 Windows 10 上运行的每台设备上。
-
UWP 不仅可以调用所有设备通用的 WinRT API,还可以调用特定于运行应用的设备系列的 API(包括 Win32 和 .NET API)。
Windows 10 支持的设备
Windows 8.1 和 Windows Phone 8.1 应用程序针对操作系统;Windows 或 Windows Phone。Windows 10 应用程序不针对操作系统,而是针对一个或多个设备系列。
设备系列也有自己的 API,为特定的设备系列添加功能。您可以从 Windows 应用商店轻松确定设备系列中可以安装和运行您的应用程序的所有设备。这是设备系列的分层表示。
UWP的优势
通用 Windows 平台 (UWP) 为开发人员提供了一些东西。他们是 –
- 适用于所有设备的一个操作系统和一个统一核心。
- 一个应用程序平台,可在每个家庭中运行应用程序。
- 一个用于提交应用程序和仪表板的开发中心。
- 所有设备的一个商店。
UWP 开发设置
需要按照以下步骤开始为 Windows 10 创建您自己的通用 Windows 平台 (UWP) 应用程序。
-
Windows 10 OS – UWP 应用程序需要最新版本的 Windows 才能开发。您也可以在 Windows 8.1 上开发 UWP 应用程序,但不支持 UI 设计器窗口。
-
Windows 10 开发人员工具– 在 Visual Studio 2015 中,您可以设计、编码、测试和调试您的 UWP 应用程序。您可以从https://dev.windows.com/en-us/downloads下载并安装免费的 Microsoft Visual Studio Community 2015
-
为 Windows 10 启用开发模式–
-
转到“开始”>“设置”。
-
选择更新和安全。
-
然后选择“对于开发人员”。
-
点击开发者模式
-
对于 UWP 应用,在设备上测试应用非常重要。
-
注册为应用程序开发人员– 您可以开始开发应用程序,但要将您的应用程序提交到商店,您需要一个开发人员帐户。您可以在此处创建您的开发者帐户https://msdn.microsoft.com/enus/library/windows/apps/bg124287.aspx
完成上述步骤后,您现在可以开始开发通用 Windows 平台 (UWP) 应用程序。
Windows 10 开发 – 第一个应用程序
在本章中,我们将在 Windows 10 上使用 XAML 和 C# 在通用 Windows 平台 (UWP) 中创建我们的第一个简单应用程序“Hello world”。我们将演示如何在 Visual Studio 中创建的单个 UWP 应用程序可以在任何平台上运行和执行Windows 10 设备。
让我们按照下面给出的步骤开始创建应用程序。
-
启动 Visual Studio 2015。
-
单击“文件”菜单并选择“新建”>“项目”。
-
将显示以下新建项目对话窗口。您可以在对话框的左窗格中看到不同类型的模板。
-
在左窗格中,您可以看到树视图。从模板 > Visual C# > Windows 中选择通用模板。
-
从中心窗格中,选择Blank App (Universal Windows)模板
-
通过在名称字段中写入UWPHelloWorld为项目命名。
-
单击“确定”以创建新的 UWP 项目。
-
您可以在解决方案资源管理器中看到新创建的项目。
-
这是一个空白的应用程序,但它包含许多文件,这是任何 UWP 应用程序的最低要求。
-
MainPage.xaml和MainPage.xaml.cs在您执行应用程序时运行。
-
默认情况下,MainPage.xaml文件包含以下信息。
<Page x:Class = ”UWPHellowWorld.MainPage” xmlns = ”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = ”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = ”using:UWPHellowWorld” xmlns:d = ”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = ”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable = ”d”> <Grid Background = ”{ThemeResource ApplicationPageBackgroundThemeBrush}”> </Grid> </Page>
-
下面给出的是MainPage.xaml.cs 中可用的默认信息。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPHellowWorld { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); } } }
-
让我们添加一些文本块、一个文本框和一个按钮,如下面的 XAML 代码所示。
<Page x:Class = ”UWPHellowWorld.MainPage” xmlns = ”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = ”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = ”using:UWPHellowWorld” xmlns:d = ”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = ”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable = ”d”> <Grid Background = ”{ThemeResource ApplicationPageBackgroundThemeBrush}”> <StackPanel HorizontalAlignment = ”Center”> <TextBlock Text = ”Hello, world!” Margin = ”20” Width = ”200” HorizontalAlignment = ”Left”/> <TextBlock Text = ”Write your name.” Margin = ”20” Width = ”200” HorizontalAlignment = ”Left”/> <TextBox x:Name = ”txtbox” Width = ”280” Margin = ”20” HorizontalAlignment = ”Left”/> <Button x:Name = ”button” Content = ”Click Me” Margin = ”20” Click = ”button_Click”/> <TextBlock x:Name = ”txtblock” HorizontalAlignment = ”Left” Margin = ”20”/> </StackPanel> </Grid> </Page>
- 下面给出的是 C# 中的点击事件按钮。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPHellowWorld { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void button_Click(object sender, RoutedEventArgs e) { if (txtbox.Text != “”) txtblock.Text = “Hello: “ + txtbox.Text; else txtblock.Text = “You have not write your name”; } } }
-
在 UWP 项目中,设计窗口中提供了设备预览选项,借助该选项,您可以轻松更改布局,以适应您为应用程序定位的设备系列中所有设备的屏幕尺寸。
-
您可以在本地计算机、模拟器或模拟器或远程设备上运行和测试您的应用程序。您可以从以下菜单中选择目标设备,如下所示 –
-
让我们在本地机器上运行上述代码,您将看到以下窗口。现在,在文本框中输入任何名称,然后单击“单击我”按钮。
-
现在,如果您想在模拟器上测试您的应用程序,您可以从菜单中选择一个特定的模拟器并执行您的应用程序。您将看到以下模拟器 –
我们建议您使用不同的设备执行上述应用程序。
Windows 10 开发 – 商店
Windows 应用商店对开发人员的好处是您可以销售您的应用程序。您可以为每个设备系列提交您的单一应用程序。
-
Windows 10 应用商店是提交应用程序的地方,以便用户可以找到您的应用程序。
-
在 Windows 8 中,商店仅限于应用程序,微软提供了许多商店,例如 Xbox 音乐商店、Xbox 游戏商店等。
-
在 Windows 8 中,所有这些都是不同的商店,但在 Windows 10 中,它被称为 Windows 商店。它的设计方式是让用户可以在一个地方找到适用于所有 Windows 10 设备的全套应用程序、游戏、歌曲、电影、软件和服务。
货币化
货币化意味着在台式机、移动设备、平板电脑和其他设备上销售您的应用程序。您可以通过多种方式在 Windows 应用商店销售应用程序和服务以赚取收入。
您可以选择以下任何一种方法 –
-
最简单的方法是使用付费下载选项在商店提交您的应用程序。
-
Trails 选项,用户可以在购买之前试用您的应用程序,但功能有限。
-
使用 Microsoft Advertising 向您的应用添加广告。
微软广告
当您向应用程序添加广告并且用户点击该特定广告时,广告商将向您付款。Microsoft Advertising 允许开发人员从 Microsoft Advertising Network 接收广告。
-
适用于通用 Windows 应用程序的 Microsoft Advertising SDK 包含在 Visual Studio 2015 安装的库中。
-
您也可以从visualstudiogallery安装它
-
现在,您可以轻松地将视频和横幅广告集成到您的应用中。
让我们看一下 XAML 中的一个简单示例,使用AdControl在您的应用程序中添加横幅广告。
-
创建一个名为UWPBannerAd的新通用 Windows 空白应用项目。
-
在解决方案资源管理器中,右键单击引用
-
选择Add References,这将打开Reference Manager对话框。
-
在左侧窗格中,选择通用 Windows 下的扩展选项并选中Microsoft Advertising SDK for XAML。
-
单击确定继续。
-
下面给出的是 XAML 代码,其中添加了一些属性的AdControl。
<Page x:Class = "UWPBannerAd.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBannerAd" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:UI = "using:Microsoft.Advertising.WinRT.UI" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel HorizontalAlignment = "Center"> <UI:AdControl ApplicationId = "d25517cb-12d4-4699-8bdc-52040c712cab" AdUnitId = "10043121" HorizontalAlignment = "Left" Height = "580" VerticalAlignment = "Top" Width = "800"/> </StackPanel> </Grid> </Page>
在本地机器上编译并执行上述代码后,您将看到以下带有 MSN 横幅的窗口。当您单击此横幅时,它将打开 MSN 站点。
您还可以在应用程序中添加视频横幅。让我们考虑另一个示例,当单击“显示广告”按钮时,它将播放 Xbox One 的视频广告。
下面给出的是 XAML 代码,我们在其中演示了如何为按钮添加一些属性和事件。
<Page x:Class = "UWPBannerAd.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBannerAd" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:UI = "using:Microsoft.Advertising.WinRT.UI" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel HorizontalAlignment = "Center"> <Button x:Name = "showAd" Content = "Show Ad" HorizontalAlignment = "Left" Margin = "138,296,0,0" VerticalAlignment = "Top" FontSize = "48" Click = "showAd_Click"/> </StackPanel> </Grid> </Page>
下面给出了 C# 中的单击事件实现。
using Microsoft.Advertising.WinRT.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPBannerAd { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { InterstitialAd videoAd = new InterstitialAd(); public MainPage() { this.InitializeComponent(); } private void showAd_Click(object sender, RoutedEventArgs e) { var MyAppId = "d25517cb-12d4-4699-8bdc-52040c712cab"; var MyAdUnitId = "11388823"; videoAd.AdReady += videoAd_AdReady; videoAd.RequestAd(AdType.Video, MyAppId, MyAdUnitId); } void videoAd_AdReady(object sender, object e){ if ((InterstitialAdState.Ready) == (videoAd.State)) { videoAd.Show(); } } } }
当上述代码在本地机器上编译和执行时,您将看到以下窗口,其中包含一个Show Ad按钮。
现在,当您点击Show Ad按钮时,它会在您的应用中播放视频。
Windows 10 开发 – XAML 控件
XAML 代表可扩展应用程序标记语言。它是一个用户界面框架,它提供了一个广泛的控件库,支持 Windows 的 UI 开发。其中一些具有可视化表示,例如 Button、Textbox 和 TextBlock 等;而其他控件用作其他控件或内容的容器,例如图像等。所有 XAML 控件都继承自“System.Windows.Controls.Control”。
XAML 新兴故事
XAML 用于许多重要的 Microsoft 平台,例如 Windows Presentation Foundation (WPF)、Silverlight 和现在的 Windows 应用程序。现在,Microsoft Office 2016 也是一个 UWP 应用家族。XAML 是一个丰富的平台,它提供了可以在 UWP 应用程序中使用的非常酷的功能和控件。
控件的完整继承层次如下所示。
布局控件
控件的布局对于应用程序的可用性非常重要和关键。它用于在您的应用程序中排列一组 GUI 元素。选择布局面板时需要考虑一些重要的事情 –
- 子元素的位置。
- 子元素的大小。
- 重叠的子元素相互叠加。
下面给出了布局控件列表–
S.No. | 控制和描述 |
---|---|
1 |
StackPanel StackPanel是一个简单而有用的 XAML 布局面板。在堆栈面板中,子元素可以根据方向属性水平或垂直排列在一行中。 |
2 |
WrapPanel 在WrapPanel 中,子元素根据orientation 属性按从左到右或从上到下的顺序排列。StackPanel 和 WrapPanel 之间的唯一区别是它不会将所有子元素堆叠到一行中,而是在没有剩余空间时将剩余元素换行到另一行。 |
3 |
DockPanel DockPanel定义了一个区域来相对于彼此排列子元素,无论是水平还是垂直。使用 DockPanel,您可以使用 Dock 属性轻松地将子元素停靠到顶部、底部、右侧、左侧和中心。 使用LastChildFill属性,最后一个子元素填充剩余空间,而不管为该元素设置的任何其他停靠值。 |
4 |
Canvas Canvas是基本的布局面板,可以使用相对于任何一侧(例如左侧、右侧、顶部和底部)的坐标来明确定位子元素。通常,Canvas 用于 2D 图形元素(例如椭圆、矩形等),但不用于 UI 元素,因为在 XAML 应用程序中调整大小、本地化或缩放时指定绝对坐标会带来麻烦。 |
5 |
Grid 网格提供了一个灵活的区域,它由行和列组成。在 Grid 中,子元素可以以表格形式排列。可以使用Grid.Row和Grid.Column属性将元素添加到任何特定的行和列。 |
6 |
SplitView SplitView代表一个有两个视图的容器;一个视图用于主要内容,另一个视图通常用于导航命令。 |
7 |
RelativePanel 相对面板定义了一个区域,您可以在该区域内相对于彼此或父面板定位和对齐子对象。 |
8 |
ViewBox ViewBox定义了一个内容装饰器,可以拉伸和缩放单个子项以填充可用空间。 |
9 |
FlipView FlipView表示一个项目的控件,它一次显示一个项目,并启用“翻转”行为以遍历其项目集合。 |
10 |
GridView GridView是一个控件,它以行和列的形式呈现项目集合,并且可以水平滚动。 |
用户界面控件
这是最终用户可见的 UI 控件列表。
S.No. | UI 控件和说明 |
---|---|
1 |
Button 响应用户输入的控件 |
2 |
Calendar 表示一个控件,该控件使用户能够使用可视日历显示来选择日期。 |
3 |
CheckBox 用户可以选择或清除的控件。 |
4 |
ComboBox 项目的下拉列表,用户可以从中进行选择。 |
5 |
ContextMenu 获取或设置上下文菜单元素,每当通过用户界面 (UI) 从此元素内请求上下文菜单时,该元素应出现。 |
6 |
DataGrid 表示在可自定义的网格中显示数据的控件。 |
7 |
DatePicker 允许用户选择日期的控件。 |
8 |
Dialogs 应用程序还可以显示额外的窗口,以便用户收集或显示重要信息。 |
9 |
Flyout 表示显示轻量级 UI 的控件,该 UI 是信息或需要用户交互。与对话框不同的是,可以通过单击或轻敲它的外部、按设备的后退按钮或按“Esc”键来轻松关闭弹出窗口。 |
10 |
Image 显示图像的控件。 |
11 |
ListBox 显示用户可以从中选择的内联项目列表的控件。 |
12 |
Menus 表示一个 Windows 菜单控件,它使您能够分层组织与命令和事件处理程序关联的元素。 |
13 |
MenuFlyout 表示显示命令菜单的浮出控件。 |
14 |
PasswordBox 用于输入密码的控件。 |
15 |
Popup 在现有内容之上,在应用程序窗口的边界内显示内容。 |
16 |
ProgressBar 通过显示条形指示进度的控件。 |
17 |
ProgressRing 通过显示环来指示不确定进度的控件。 |
18 |
RadioButton 允许用户从一组选项中选择一个选项的控件。 |
19 |
RichEditBox 允许用户编辑包含格式化文本、超链接和图像等内容的富文本文档的控件。 |
20 |
ScrollViewer 允许用户平移和缩放其内容的容器控件。 |
21 |
SearchBox 允许用户输入搜索查询的控件。 |
22 |
Slider 允许用户通过沿轨道移动 Thumb 控件从一系列值中进行选择的控件。 |
23 |
TextBlock 显示文本的控件。 |
24 |
TimePicker 允许用户设置时间值的控件。 |
25 |
ToggleButton 可以在两种状态之间切换的按钮。 |
26 |
ToolTip 显示元素信息的弹出窗口。 |
27 |
Window 提供最小化/最大化选项、标题栏、边框和关闭按钮的根窗口。 |
下面给出了一个示例,其中包含SplitView中不同类型的控件。在 XAML 文件中,使用一些属性和事件创建了不同的控件。
<Page x:Class = "UWPControlsDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPControlsDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin = "20"> <StackPanel Orientation = "Horizontal"> <ToggleButton x:Name = "HamburgerButton" FontFamily = "Segoe MDL2 Assets" Content = "" Checked = "HandleCheck" Unchecked = "HandleUnchecked" HorizontalAlignment = "Center"/> <AppBarButton Icon = "Like" /> <AppBarButton Icon = "Dislike" /> <AppBarSeparator/> <AppBarButton Icon = "Accept" /> <AppBarButton Icon = "Add" /> </StackPanel> <SplitView x:Name = "splitView" DisplayMode = "Inline" OpenPaneLength = "296"> <SplitView.Pane> <StackPanel> <TextBlock Text = "SplitView Pane" FontSize = "36" VerticalAlignment = "Center" HorizontalAlignment = "Center" Margin = "10"/> <Button Content = "Options" Margin = "10"> <Button.Flyout> <MenuFlyout> <MenuFlyoutItem Text = "Reset"/> <MenuFlyoutSeparator/> <MenuFlyoutItem Text = "Repeat"/> <MenuFlyoutItem Text = "Shuffle"/> </MenuFlyout> </Button.Flyout> </Button> </StackPanel> </SplitView.Pane> <StackPanel> <TextBlock Text = "SplitView Content" FontSize = "36" VerticalAlignment = "Center" HorizontalAlignment = "Center" Margin = "10"/> <Border BorderThickness = "3" BorderBrush = "Red" Margin = "5"> <StackPanel Orientation = "Horizontal"> <TextBlock Text = "Hyperlink example" Margin = "5"/> <HyperlinkButton Content = "www.microsoft.com" NavigateUri = "http://www.microsoft.com"/> </StackPanel> </Border> <RelativePanel BorderBrush = "Red" BorderThickness = "2" CornerRadius = "10" Padding = "12" Margin = "5"> <TextBlock x:Name = "txt" Text = "Relative Panel example" RelativePanel.AlignLeftWithPanel = "True" Margin = "5,0,0,0"/> <TextBox x:Name = "textBox1" RelativePanel.RightOf = "btn" Margin = "5,0,0,0"/> <Button x:Name = "btn" Content = "Name" RelativePanel.RightOf = "txt" Margin = "5,0,0,0"/> </RelativePanel> <FlipView Height = "400" Margin = "10" Width = "400"> <Image Source = "Images/DSC_0104.JPG"/> <Image Source = "Images/DSC_0080.JPG"/> <Image Source = "Images/DSC_0076.JPG"/> <Image Source = "Images/thGTF7BWGW.jpg"/> </FlipView> </StackPanel> </SplitView> </StackPanel> </Grid> </Page>
下面给出的是C# 中的事件实现。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPControlsDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void HandleCheck(object sender, RoutedEventArgs e) { splitView.IsPaneOpen = true; } private void HandleUnchecked(object sender, RoutedEventArgs e) { splitView.IsPaneOpen = false; } } }
编译并执行上述代码后,您将看到以下窗口 –
当您单击左上角的汉堡按钮时,它将打开/关闭SplitView窗格。
在SplitView窗格中,您可以看到Flyout、MenuFlyout和FlipView控件。
在SplitView Content 中,可以看到 Hyperlink、Relative Panel、ViewBox 等按钮和文本框控件。
Windows 10 开发 – 数据绑定
数据绑定是 XAML 应用程序中的一种机制,它为 Windows 运行时应用程序使用部分类来显示数据和与数据交互提供了一种简单易行的方法。在这种机制中,数据的管理与数据的显示方式完全分离。
数据绑定允许数据在用户界面上的 UI 元素和数据对象之间流动。当建立绑定并且数据或您的业务模型发生变化时,它会自动将更新反映到 UI 元素,反之亦然。也可以不绑定到标准数据源,而是绑定到页面上的另一个元素。数据绑定可以是 –
- 单向数据绑定
- 双向数据绑定
- 元素绑定
单向数据绑定
在单向绑定中,数据从其源(保存数据的对象)绑定到其目标(显示数据的对象)。
让我们看一个单向数据绑定的简单示例。下面给出的是 XAML 代码,其中使用一些属性创建了四个文本块。
<Page x:Class = "OneWayDataBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:OneWayDataBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Name = "Display"> <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> <TextBlock Text = "Name: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "100" Text = "{Binding Name}"/> </StackPanel> <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> <TextBlock Text = "Title: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "200" Text = "{Binding Title}" /> </StackPanel> </StackPanel> </Grid> </Page>
两个文本块的Text属性静态设置为“Name”和“Title”,而文本块的另外两个Text属性绑定到Employee类的类变量“Name”和“Title”,如下所示。
using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace OneWayDataBinding { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); DataContext = Employee.GetEmployee(); } } public class Employee { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee() { Name = "Waqar Ahmed", Title = "Development Manager" }; return emp; } } }
在Employee 类中,我们有变量Name和Title以及一个静态方法,在该方法中员工对象被初始化并返回该员工对象。因此,我们正在绑定属性 Name 和 Title,但我们还没有选择该属性所属的对象。简单的方法是将一个对象分配给DataContext,我们在MainPage构造函数中绑定其属性。
当您运行此应用程序时,您可以立即在MainWindow 中看到您已成功绑定到该 Employee 对象的 Name 和 Title。
双向数据绑定
在双向绑定中,用户能够通过用户界面修改数据并在源中更新该数据。例如,如果在用户查看视图时源发生更改,您希望更新视图。
让我们看看下面给出的示例,其中使用一些属性和事件创建了两个标签、两个文本框和一个按钮。
<Page x:Class = "TwoWayDataBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:TwoWayDataBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "200" /> </Grid.ColumnDefinitions> <TextBlock Name = "nameLabel" Margin = "200,20,0,0">Name:</TextBlock> <TextBox Name = "nameText" Grid.Column = "1" Margin = "10,20,0,0" Text = "{Binding Name, Mode = TwoWay}"/> <TextBlock Name = "ageLabel" Margin = "200,20,0,0" Grid.Row = "1">Age:</TextBlock> <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10,20,0,0" Text = "{Binding Age, Mode = TwoWay}"/> <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> <Button Content = "Display" Click = "Button_Click" Margin = "200,20,0,0"/> <TextBlock x:Name = "txtblock" Margin = "200,20,0,0"/> </StackPanel> </Grid> </Page>
我们可以观察到以下情况 –
-
两个文本框的 Text 属性都绑定到“Name”和“Age”,它们是Person 类的类变量,如下所示。
-
在Person 类中,我们只有两个变量 – Name 和 Age,其对象在MainWindow类中初始化。
-
在 XAML 代码中,我们绑定到属性 – Name和Age,但我们没有选择该属性所属的对象。
-
更简单的方法是将一个对象分配给DataContext,我们在 C# 代码中绑定其属性,如下面的MainWindowconstructor所示。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace TwoWayDataBinding { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { Person person = new Person { Name = "Salman", Age = 26 }; public MainPage() { this.InitializeComponent(); this.DataContext = person; } private void Button_Click(object sender, RoutedEventArgs e) { string message = person.Name + " is " + person.Age + " years old"; txtblock.Text = message; } } public class Person { private string nameValue; public string Name { get { return nameValue; } set { nameValue = value; } } private double ageValue; public double Age { get { return ageValue; } set { if (value != ageValue) { ageValue = value; } } } } }
上述代码编译执行后,会看到如下窗口。单击显示按钮。
让我们更改名称和年龄,然后再次单击显示按钮。
您可以看到在单击按钮‘Display’ 中,文本框的文本未用于显示TextBlock上的数据,而是使用了类变量。
我建议您在两种情况下执行上述代码,以便更好地理解。
元素绑定
也可以不绑定到标准数据源,而是绑定到页面上的另一个元素。让我们创建一个名为ElementBinding的应用程序,其中创建了一个 Slider 和一个 Rectangle,并使用滑块绑定了矩形的宽度和高度。下面给出的是 XAML 中的代码。
<Page x:Class = "ElementBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ElementBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel VerticalAlignment = "Center" HorizontalAlignment = "Center"> <Rectangle Height = "100" Width = "100" Fill = "SteelBlue" RenderTransformOrigin = "0.5,0.5" Margin = "50"> <Rectangle.RenderTransform> <CompositeTransform ScaleX = "{Binding Value, ElementName = MySlider}" ScaleY = "{Binding Value, ElementName = MySlider}"/> </Rectangle.RenderTransform> </Rectangle> <Slider Minimum = ".5" Maximum = "2.0" StepFrequency = ".1" x:Name = "MySlider" /> </StackPanel> </Grid> </Page>
上述代码编译执行后,会看到如下窗口。
使用滑块,您可以更改矩形的大小,如下所示。
Windows 10 开发人员 – XAML 性能
应用程序的性能(例如您的应用程序在启动时出现的速度或导航以显示下一个内容等)非常重要。
应用程序的性能会受到很多因素的影响,包括 XAML 呈现引擎解析应用程序中所有 XAML 代码的能力。XAML 是用于创建 UI 的非常强大的工具,但通过使用现在可在 Windows 10 应用程序中使用的新技术,它可以变得更加健壮。
例如,在您的应用程序中,您希望在加载页面时显示某些内容,稍后再不需要它。也有可能在启动时您不需要加载所有 UI 元素。
在 Windows 10 应用程序中,XAML 中添加了一些新功能,从而提高了 XAML 性能。
任何通用 Windows 应用程序的性能都可以通过以下技术提高;
- 渐进式渲染
- 延迟加载
渐进式渲染
在 Windows 10 中,XAML 中引入了两个非常酷的新功能。他们是 –
x:绑定
它是 XAML 中引入的一种用于绑定的新语法,其工作方式几乎与Binding语法相同。x:Bind有两个主要区别;它提供编译时语法验证和更好的性能。
X:相位
它提供了在数据模板中优先呈现 XAML 控件的能力。每个 UI 元素可能只指定一个阶段。如果是这样,这将适用于元素上的所有绑定。如果未指定阶段,则假定为阶段 0。
在通用 Windows 平台 (UWP) 应用程序中,这两个新功能提供了性能改进。它还可用于迁移到 Windows 10 的现有 Windows 8.x 应用程序。
下面给出了一个示例,其中使用x:Bind关键字将员工对象与GridView绑定。
<Page x:Class = "XAMLPhase.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:XAMLPhase" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <GridView Name = "Presidents" ItemsSource = "{Binding}" Height = "300" Width = "400" Margin = "50"> <GridView.ItemTemplate> <DataTemplate x:DataType = "local:Employee"> <StackPanel Orientation = "Horizontal" Margin = "2"> <TextBlock Text = "{x:Bind Name}" Width = "95" Margin = "2" /> <TextBlock Text = "{x:Bind Title}" Width = "95" Margin = "2" x:Phase = "1"/> </StackPanel> </DataTemplate> </GridView.ItemTemplate> </GridView> </Grid> </Page>
在上面的 XAML 代码中,x:Phase = “1”是用 Title 定义的。因此,在第一阶段,将呈现Name,然后将呈现Title。
下面给出的是C# 中的Employee 类实现。
using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace XAMLPhase { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); DataContext = Employee.GetEmployees(); } } public class Employee : INotifyPropertyChanged { private string name; public string Name { get { return name; } set { name = value; RaiseProperChanged(); } } private string title; public string Title { get { return title; } set { title = value; RaiseProperChanged(); } } public static Employee GetEmployee() { var emp = new Employee() { Name = "Waqas", Title = "Software Engineer" }; return emp; } public event PropertyChangedEventHandler PropertyChanged; private void RaiseProperChanged( [CallerMemberName] string caller = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(caller)); } } public static ObservableCollection<Employee> GetEmployees() { var employees = new ObservableCollection<Employee>(); employees.Add(new Employee() { Name = "Ali", Title = "Developer" }); employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" }); employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" }); employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" }); employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" }); employees.Add(new Employee() { Name = "Waqar", Title = "Manager" }); return employees; } } }
执行上述代码后,您将看到以下窗口。
在X:第一阶段用X:绑定用于渲染的ListView和GridView的增量项目,提高了平移体验。
延迟加载
延迟加载是一种技术,可用于通过在应用程序启动时减少 XAML UI 元素的数量来最小化启动加载时间。如果您的应用程序包含 30 个 UI 元素并且用户在启动时不需要所有这些元素,那么所有这些不需要的元素可以通过延迟来节省一些加载时间。
x:DeferLoadStrategy = “Lazy”延迟元素及其子元素的创建,这会减少启动时间,但会略微增加内存使用量。
可以通过使用元素上定义的名称调用FindName来实现/创建延迟元素。
一旦创建了延迟元素,就会发生几件事 –
-
将引发元素上的 Loaded 事件。
-
将评估元素上的任何绑定。
-
如果应用程序注册为接收包含延迟元素的属性的属性更改通知,则将引发该通知。
下面给出了一个示例,其中x:DeferLoadStrategy = “Lazy”用于包含四个文本块的网格,并且不会在您的应用程序启动时加载,直到您加载它。
<Page x:Class = "UWPDeferredLoading.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPDeferredLoading" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid x:Name = "DeferredGrid" x:DeferLoadStrategy = "Lazy" Margin = "50"> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "Auto" /> </Grid.ColumnDefinitions> <TextBlock Height = "100" Width = "100" Text = "TextBlock 1" Margin = "0,0,4,4" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 2" Grid.Column = "1" Margin = "4,0,0,4" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 3" Grid.Row = "1" Margin = "0,4,4,0" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 4" Grid.Row = "1" Grid.Column = "1" Margin = "4,4,0,0" /> </Grid> <Button x:Name = "RealizeElements" Content = "Show Elements" Click = "RealizeElements_Click" Margin = "50"/> </Grid> </Page>
以下程序是点击事件的实现,其中网格加载到应用程序主页。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPDeferredLoading { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void RealizeElements_Click(object sender, RoutedEventArgs e) { this.FindName("DeferredGrid"); // This will realize the deferred grid } } }
当上面的代码在编译和执行时,你只会看到一个按钮。该的TextBlocks不会在启动时加载。
现在,当您单击Show Elements按钮时,它将加载文本块,这将提高应用程序的启动性能。
Windows 10 开发 – 自适应设计
在 Windows 10 中,通用 Windows 平台 (UWP) 应用程序现在将在许多设备系列上运行,例如 –
-
桌面设备系列– 平板电脑、笔记本电脑、PC
-
移动设备系列– Windows Phones, phablets
-
物联网设备系列– 可穿戴设备或家用电器等紧凑型设备
-
团队设备系列– Surface hub
每个设备系列都有自己的屏幕和窗口大小。那么如何设计一个应用程序,在具有截然不同的屏幕尺寸和不同输入方法的多种设备上提供出色的用户体验?
为多个器件系列设计应用程序需要一些额外的考虑、规划和设计。Windows 10 UWP 提供了一组内置功能和通用构建块,可以更轻松地针对多个设备进行设计,并在平台控件支持的不同屏幕和窗口大小之间自动缩放。
新的内置功能
以下是开发人员在创建 UWP 应用程序时可以使用的新功能。这些功能是自动且免费的。
有效像素和平台缩放
当您的 UWP 应用程序在 Windows 10 支持的任何设备上运行时,则 –
-
该系统使用一种算法来规范控件、字体和其他 UI 元素在它当前运行的设备的屏幕上的显示方式。
-
缩放算法,控制观看距离和屏幕密度(每英寸像素数)以优化预期尺寸(而不是物理尺寸)。
-
缩放算法可确保 10 英尺外 Surface Hub 上的 36 像素字体对用户来说与几英寸外的 5 英寸手机上的 36 像素字体一样可读。
通用输入和智能交互
通用 Windows 平台具有内置的智能交互输入系统,可以理解所有设备的输入。例如,当你在你的应用程序中设计一个点击交互时,你不需要知道点击是来自实际的鼠标点击还是手指的点击。系统会自动为您完成。
通用积木
有一些有价值的构建块,可以更轻松地为通用 Windows 平台 (UWP) 中的多个设备系列设计应用程序。
通用控件
UWP 提供了一组通用控件,保证在所有 Windows 10 设备上都能正常工作。
-
此“通用控件”列表包含常用控件,如单选按钮、组合框和文本框等。
-
它还包含一些复杂的控件,如网格视图和列表视图,可以从数据流和模板生成项目列表。
通用样式
UWP 应用程序会自动获取一组默认样式,为您提供这些功能 –
-
一组样式,可自动为您的应用提供浅色或深色主题。
-
交互的默认动画。
-
自动支持高对比度模式。
-
自动支持其他语言。我们的默认样式会自动为 Windows 支持的每种语言选择正确的字体。您甚至可以在同一个应用程序中使用多种语言,它们将正确显示。
Windows 10 开发 – 自适应 UI
通用 Windows 平台 (UWP) 应用程序可以在许多不同的设备上运行,每个设备都有自己的输入形式、屏幕分辨率、DPI 密度和其他独特的特性。
在 Windows 10 中,借助新的通用控件、布局面板和工具,您可以轻松地调整您的 UI,以适应您的应用程序可能在其上运行的设备。例如,当您的 UWP 应用程序在台式计算机、移动设备或平板电脑上运行时,您可以定制 UI 以利用不同的屏幕分辨率、屏幕尺寸和 DPI 密度。
在 Windows 10 中,您可以轻松地将 UI 定位到具有以下功能的多个设备 –
-
您可以使用通用控件和布局面板针对不同的屏幕分辨率和屏幕尺寸增强 UI。
-
通用输入处理允许您通过触摸板、笔、鼠标、键盘或控制器(如 Microsoft Xbox 控制器)接收输入。
-
借助工具,您可以设计可以适应不同屏幕分辨率的应用程序 UI。
-
自适应缩放会根据设备之间的分辨率和 DPI 差异进行调整。
在 Windows 10 中,您可以按您想要的任何方式轻松排列、调整大小和定位应用程序。它还为用户以他们想要的方式使用您的应用程序提供了某种灵活性。在 Windows 10 中,有多种方法可以在 UWP 应用程序中实现响应式技术,因此无论屏幕或窗口大小如何,它看起来都很棒。
视觉状态管理器
在 Windows 10 中,VisualStateManager类具有两种新机制,您可以借助它们在 UWP 应用程序中实现响应式设计。新的VisualState.StateTriggers允许开发人员检查某些条件,如窗口高度或窗口宽度,然后VisualState.Setters API 定义视觉状态以响应这些特定条件。
让我们看一下下面给出的示例,其中在堆栈面板中添加了一些控件。
<Page x:Class = "UWPAdaptiveUI.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdaptiveUI" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <!-- VisualState to be triggered when window width is >=720 effective pixels. --> <AdaptiveTrigger MinWindowWidth = "720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "myPanel.Orientation" Value = "Horizontal" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <StackPanel x:Name = "myPanel" Orientation = "Vertical"> <TextBlock Text = "Windows 10 Tutorials: Text block 1. " Style = "{ThemeResource BodyTextBlockStyle}"/> <TextBlock Text = "Windows 10 Tutorials: Text block 2. " Style = "{ThemeResource BodyTextBlockStyle}"/> <TextBlock Text = "Windows 10 Tutorials: Text block 3. " Style = "{ThemeResource BodyTextBlockStyle}"/> </StackPanel> </Grid> </Page>
现在VisualStateManager,将根据窗口的宽度调整堆栈面板的方向。如果宽度 >= 720,则方向将变为水平,否则将保持垂直。当上述代码编译执行后,您将看到以下窗口,其中包含三个按垂直顺序排列的文本块。
让我们调整上述窗口的宽度,您将看到以下窗口 –
现在您可以看到文本块处于水平顺序。
相对面板
RelativePanel可用于通过表达元素之间的空间关系来布置 UI 元素。让我们以在相关面板中创建一些矩形为例。
<Page x:Class = "UWPAdaptiveUI.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdaptiveUI" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth = "720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "GreenRect.(RelativePanel.RightOf)" Value = "BlueRect" /> <Setter Target = "GreenRect.(RelativePanel.AlignRightWithPanel)" Value = "True" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <RelativePanel BorderBrush = "Gray" BorderThickness = "10"> <Rectangle x:Name = "RedRect" Fill = "Red" MinHeight = "100" MinWidth = "100"/> <Rectangle x:Name = "BlueRect" Fill = "Blue" MinHeight = "100" MinWidth = "100" RelativePanel.RightOf = "RedRect" /> <!-- Width is not set on the green and yellow rectangles. It's determined by the RelativePanel properties. --> <Rectangle x:Name = "GreenRect" Fill = "Green" MinHeight = "100" RelativePanel.Below = "BlueRect" RelativePanel.AlignLeftWith = "RedRect" RelativePanel.AlignRightWith = "BlueRect"/> <Rectangle Fill = "Yellow" MinHeight = "100" RelativePanel.Below = "GreenRect" RelativePanel.AlignLeftWith = "BlueRect" RelativePanel.AlignRightWithPanel = "True"/> </RelativePanel> </Grid> </Page>
上述代码编译执行后,会看到如下窗口。
当您调整上述窗口的大小时,您将看到绿色矩形现在调整到蓝色矩形左侧的顶行,如下所示。
Windows 10 开发 – 自适应代码
在本章中,我们将演示如何在 Windows 10 支持的不同设备上采用您的应用程序。我们已经了解了如何采用您的 UI 以及 UWP 应用程序中使用的所有技巧、技术和控件。
现在,我们将学习采用您的代码,因为
-
所有设备的应用程序代码都不相同。
-
所使用的 API,尤其是用于 Xbox 的 API,将无法用于移动设备。HoloLens 等也是如此。
自适应代码可以有条件地点亮您的应用程序并仅在特定设备系列和/或特定版本的平台/扩展 API 上运行时才执行代码。
编写代码
在 Windows 10 中,你可以使用 C++、C#、Visual Basic 或 JavaScript 在 Visual Studio 中实现 UWP 应用程序。
-
借助 C# 和 Visual Basic,您可以使用 XAML 进行 UI 设计。
-
使用 C++,您可以使用 DirectX 而不是使用 XAML。
-
对于 JavaScript,您可以将 HTML 用于表示层,这是一种跨平台的 Web 标准。
Windows 核心 API 以相同的方式在所有设备上运行,其中包含您的代码和 UI 所需的大部分功能。但是,对于为特定设备系列量身定制的代码和UI,您需要使用自适应代码和自适应UI。
调用目标设备系列未实现的 API –
用户界面很容易适应不同的屏幕,但不同的设备系列不仅有不同的屏幕尺寸,它还有很多。
-
例如,手机有一些硬件按钮,如返回和摄像头,这些按钮在其他设备(如 PC)上可能不可用。
-
默认情况下,核心 API 包含大部分功能,适用于所有设备,但可以通过引用 UWP 应用程序中的扩展 SDK 来使用特定于设备的功能,就像外部程序集一样。
要添加您的应用程序中需要的任何特定扩展 SDK,请按照以下步骤操作 –
-
右键单击References。
-
选择“添加引用…”。将打开以下对话框。
-
添加扩展就像添加项目引用一样简单。
-
现在您可以从列表中添加任何扩展 SDK,包括桌面扩展、物联网扩展和移动扩展等。
桌面和移动扩展是两种最常见的平台扩展 SDK。例如,移动扩展启用使用硬件相机按钮所需的 API。
您可以使用Windows.Foundation.Metadata.ApiInformation类方法检查设备功能,如果当前设备支持该类型,则该方法返回布尔输出。例如,您可以使您的 Windows 应用程序使用具有以下代码的相机按钮 –
bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.Phone.UI.Inpu t.HardwareButtons"); if (isHardwareButtonsAPIPresent) { Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed; }
只有在设备上启用了移动扩展 SDK 时,手机摄像头按钮代码才会执行。同样,您还可以使用IsEventPresent、IsMethodPresent、IsPropertyPresent而不是IsTypePresent来检查当前 API 版本中的任何特定事件、方法或属性,如下所示。
bool isHardwareButtons_CameraPressedAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsEventPresent ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");
UWP 中的 Win32 API
使用 C++/CX 编写的通用寡妇平台 (UWP) 应用程序或 Windows 运行时组件可以访问 Win32 API,它们现在也是 UWP 的一部分。所有 Windows 10 设备系列都可以通过将您的应用程序与Windowsapp.lib链接来实现 Win32 API 。
Windowsapp.lib是一个“伞形”库,为 UWP API 提供导出。链接到Windowsapp.lib将添加到您的应用程序对所有 Windows 10 设备系列中存在的dll 的依赖项。
让我们看一个简单的例子,其中应用程序同时针对桌面和手机。因此,当应用程序在桌面上运行时,不会显示状态栏,但在手机上运行相同的应用程序时,它会显示状态栏。
下面给出了添加不同控件的 XAML 代码。
<Page x:Class = "UWPAdoptiveCode.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdoptiveCode" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Page.Background> <SolidColorBrush Color = "Green"/> </Page.Background> <Page.BottomAppBar> <CommandBar x:Name = "commandBar" > <AppBarButton Icon = "Accept" Label = "appbarbutton"/> <AppBarButton Icon = "Cancel" Label = "appbarbutton"/> </CommandBar> </Page.BottomAppBar> <Grid Background = "AliceBlue"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <local:DeviceFamilyTrigger DeviceFamily = "Desktop" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "StatusBarControls.Visibility" Value = "Collapsed"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <StackPanel HorizontalAlignment = "Left" Margin = "75,164,0,0" VerticalAlignment = "Top" > <RadioButton x:Name = "ShowAppBarRadioButton" Content = "Show AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" IsChecked = "True" Checked = "RadioButton_Checked"/> <RadioButton x:Name = "ShowOpaqueAppBarRadioButton" Content = "Show Transparent AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> <RadioButton x:Name = "HideAppBarRadioButton" Content = "Hide AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> </StackPanel> <StackPanel x:Name = "StatusBarControls" Orientation = "Vertical" Margin = "75,350,0,0" Visibility = "Visible"> <CheckBox x:Name = "StatusBarBackgroundCheckBox" Content = "Set StatusBar Background" Checked = "StatusBarBackgroundCheckBox_Checked" Unchecked = "StatusBarBackgroundCheckBox_Unchecked"/> <CheckBox x:Name = "StatusBarHiddenCheckBox" Content = "Set StatusBar Hidden" Checked = "StatusBarHiddenCheckBox_Checked" Unchecked = "StatusBarHiddenCheckBox_Unchecked"/> </StackPanel> </Grid> </Page>
下面给出了不同事件的 C# 实现。
using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPAdoptiveCode { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { private Color? DefaultTitleBarButtonsBGColor; private Color? DefaultTitleBarBGColor; public MainPage() { this.InitializeComponent(); //Windows.UI.ViewManagement.ApplicationView.GetForCurrentView(). VisibleBoundsCh anged += MainPage_VisibleBoundsChanged; var viewTitleBar = Windows.UI.ViewManagement.ApplicationView. GetForCurrentView().TitleBar; DefaultTitleBarBGColor = viewTitleBar.BackgroundColor; DefaultTitleBarButtonsBGColor = viewTitleBar.ButtonBackgroundColor; } private void RadioButton_Checked(object sender, RoutedEventArgs e) { // Bottom AppBar shows on Desktop and Mobile if (ShowAppBarRadioButton != null) { if (ShowAppBarRadioButton.IsChecked.HasValue && (ShowAppBarRadioButton.IsChecked.Value == true)) { commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; commandBar.Opacity = 1; } else { commandBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } } if (ShowOpaqueAppBarRadioButton != null) { if (ShowOpaqueAppBarRadioButton.IsChecked.HasValue && (ShowOpaqueAppBarRadioButton.IsChecked.Value == true)){ commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; commandBar.Background.Opacity = 0; } else{ commandBar.Background.Opacity = 1; } } } private void StatusBarHiddenCheckBox_Checked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync(); } } private void StatusBarHiddenCheckBox_Unchecked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().ShowAsync(); } } private void StatusBarBackgroundCheckBox_Checked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundColor = Windows.UI.Colors.Blue; Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundOpacity = 1; } } private void StatusBarBackgroundCheckBox_Unchecked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundOpacity = 0; } } } public class DeviceFamilyTrigger : StateTriggerBase{ //private variables private string _deviceFamily; //Public property public string DeviceFamily { get { return _deviceFamily; } set{ _deviceFamily = value; var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext. GetForCurrentView().Qua lifierValues; if (qualifiers.ContainsKey("DeviceFamily")) SetActive(qualifiers["DeviceFamily"] == _deviceFamily); else SetActive(false); } } } }
当上面给出的代码在移动设备上编译和执行时,您将看到以下窗口。
您可以使用复选框更改状态栏的背景颜色,如图所示。
您还可以隐藏状态栏。
现在,当您在桌面设备上运行相同的应用程序时,您将看到以下窗口,其中状态栏和特定于状态栏的复选框不可见。
Windows10 开发 – 文件管理
在任何应用程序中,最重要的事情之一就是数据。如果您是.net开发人员,您可能了解隔离存储,并且通用 Windows 平台 (UWP) 应用程序遵循相同的概念。
文件位置
这些是您的应用程序可以访问数据的区域。该应用程序包含一些区域,该区域是该特定应用程序的私有区域,其他区域无法访问,但还有许多其他区域,您可以在其中存储和保存文件中的数据。
下面给出了每个文件夹的简要说明。
S.No. | 文件夹和说明 |
---|---|
1 |
App package folder 包管理器将应用程序的所有相关文件安装到应用程序包文件夹中,应用程序只能从该文件夹中读取数据。 |
2 |
Local folder 应用程序将本地数据存储到本地文件夹中。它可以将数据存储到存储设备上的限制。 |
3 |
Roaming folder 与应用程序相关的设置和属性存储在漫游文件夹中。其他设备也可以访问此文件夹中的数据。每个应用程序的大小限制为 100KB。 |
4 |
Temp Folder 使用临时存储并不能保证在您的应用程序再次运行时它仍然可用。 |
5 |
Publisher Share 来自同一发布者的所有应用程序的共享存储。它在应用程序清单中声明。 |
6 |
Credential Locker 用于密码凭证对象的安全存储。 |
7 |
OneDrive OneDrive 是 Microsoft 帐户附带的免费在线存储。 |
8 |
Cloud 将数据存储在云端。 |
9 |
Known folders 这些文件夹是已知的文件夹,例如 My Pictures、Videos 和 Music。 |
10 |
Removable storage USB 存储设备或外部硬盘驱动器等。 |
文件处理 API
在 Windows 8 中,引入了用于文件处理的新 API。这些 API 位于Windows.Storage和Windows.Storage.Streams命名空间中。您可以使用这些 API 代替System.IO.IsolatedStorage命名空间。通过使用这些 API,可以更轻松地将您的 Windows Phone 应用程序移植到 Windows 应用商店,并且您可以轻松地将您的应用程序升级到 Windows 的未来版本。
要访问本地、漫游或临时文件夹,您需要调用这些 API –
StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFolder roamingFolder = ApplicationData.Current.RoamingFolder; StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder;
要在本地文件夹中创建一个新文件,请使用以下代码 –
StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
这是打开新创建的文件并在该文件中写入一些内容的代码。
using (IRandomAccessStream textStream = await textFile.OpenAsync(FileAccessMode.ReadWrite)) { using (DataWriter textWriter = new DataWriter(textStream)){ textWriter.WriteString(contents); await textWriter.StoreAsync(); } }
您可以从本地文件夹再次打开同一个文件,如下面的代码所示。
using (IRandomAccessStream textStream = await textFile.OpenReadAsync()) { using (DataReader textReader = new DataReader(textStream)){ uint textLength = (uint)textStream.Size; await textReader.LoadAsync(textLength); contents = textReader.ReadString(textLength); } }
为了理解数据的读写是如何工作的,让我们看一个简单的例子。下面给出了添加不同控件的 XAML 代码。
<Page x:Class = "UWPFileHandling.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPFileHandling" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "readFile" Content = "Read Data From File" HorizontalAlignment = "Left" Margin = "62,518,0,0" VerticalAlignment = "Top" Height = "37" Width = "174" Click = "readFile_Click"/> <TextBox x:FieldModifier = "public" x:Name = "textBox" HorizontalAlignment = "Left" Margin = "58,145,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "276" Width = "245"/>. <Button x:Name = "writeFile" Content = "Write Data to File" HorizontalAlignment = "Left" Margin = "64,459,0,0" VerticalAlignment = "Top" Click = "writeFile_Click"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" Margin = "386,149,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "266" Width = "250" Foreground = "#FF6231CD"/> </Grid> </Page>
下面给出了不同事件的 C# 实现以及用于读取和写入数据到文本文件的FileHelper类的实现。
using System; using System.IO; using System.Threading.Tasks; using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPFileHandling { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public partial class MainPage : Page { const string TEXT_FILE_NAME = "SampleTextFile.txt"; public MainPage(){ this.InitializeComponent(); } private async void readFile_Click(object sender, RoutedEventArgs e) { string str = await FileHelper.ReadTextFile(TEXT_FILE_NAME); textBlock.Text = str; } private async void writeFile_Click(object sender, RoutedEventArgs e) { string textFilePath = await FileHelper.WriteTextFile(TEXT_FILE_NAME, textBox.Text); } } public static class FileHelper { // Write a text file to the app's local folder. public static async Task<string> WriteTextFile(string filename, string contents) { StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream textStream = await textFile.OpenAsync(FileAccessMode.ReadWrite)){ using (DataWriter textWriter = new DataWriter(textStream)){ textWriter.WriteString(contents); await textWriter.StoreAsync(); } } return textFile.Path; } // Read the contents of a text file from the app's local folder. public static async Task<string> ReadTextFile(string filename) { string contents; StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.GetFileAsync(filename); using (IRandomAccessStream textStream = await textFile.OpenReadAsync()){ using (DataReader textReader = new DataReader(textStream)){ uint textLength = (uint)textStream.Size; await textReader.LoadAsync(textLength); contents = textReader.ReadString(textLength); } } return contents; } } }
上述代码编译执行后,会看到如下窗口。
现在,您在文本框中写入一些内容,然后单击“将数据写入文件”按钮。程序会将数据写入本地文件夹中的文本文件。如果单击“从文件中读取数据”按钮,程序将从位于本地文件夹中的同一文本文件中读取数据并将其显示在文本块上。
Windows 10 开发 – SQLite 数据库
在许多应用程序中,存在某些类型的数据,它们彼此之间存在某种关系。这些类型的数据难以存储在文件中,可以存储在数据库中。
如果您熟悉任何应用程序中的数据库类型,例如 SQL server 或 Oracle 数据库,那么了解SQLite 数据库是非常容易的。
什么是 SQLite?
SQLite 是一个软件库,它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。
重要功能是 –
-
SQLite 是世界上部署最广泛的数据库引擎。
-
SQLite 的源代码是开源的。
-
由于其便携性和占用空间小,它对游戏和移动应用程序开发产生了巨大影响。
SQLite 的优点
以下是 SQLite 的优点 –
- 它是一个非常轻量级的数据库。
- 它是独立于平台的,适用于所有平台。
- 它的内存占用很小。
- 这是可靠的。
- 无需任何设置和安装。
- 它没有依赖关系。
要在通用 Windows 平台 (UWP) 应用程序中使用SQLite,您需要按照以下步骤操作。
-
创建一个名为UWPSQLiteDemo的新通用 Windows 空白应用程序。
-
转到“工具”菜单并选择“扩展和更新”。将打开以下对话框。
- 选择扩展和更新后,将打开以下窗口。
-
现在选择Online选项并从左侧窗格中搜索 SQLite。
-
下载并安装 SQLite for Universal App Platform。
-
现在,再次转到“工具”菜单并选择NuGet 包管理器 > 包管理器控制台菜单选项,如下所示。
-
在包管理器控制台中编写以下命令并按 Enter 执行此命令 –
Install-Package SQLite.Net-PCL
-
现在,右键点击引用在解决方案资源管理,然后选择添加引用。
- 将打开以下对话框。
-
在Universal Windows下的左侧窗格中选择Extensions,在中间窗格中选中 SQLite for Universal App Platform,然后单击 Ok。
-
现在您已准备好在 UWP 应用程序中使用 SQLite。
您可以使用以下代码创建数据库。
string path = Path.Combine(Windows.Storage.ApplicationData. Current.LocalFolder.Path, "db.sqlite"); SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
要创建表,您需要使用表名对象调用CreateTable方法。
conn.CreateTable<Customer>();
您可以使用以下代码将数据插入表中。
conn.Insert(new Customer(){ Name = textBox.Text, Age = textBox1.Text });
下面给出的是从表中检索数据的代码。
var query = conn.Table<Customer>(); string id = ""; string name = ""; string age = ""; foreach (var message in query) { id = id + " " + message.Id; name = name + " " + message.Name; age = age + " " + message.Age; }
通过一个简单的示例,让我们了解如何创建数据库、表以及如何从数据库中插入和检索数据。我们将添加姓名和年龄,然后我们将从表中检索相同的数据。下面给出了添加不同控件的 XAML 代码。
<Page x:Class = "UWPSQLiteDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPSQLiteDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}" > <Button x:Name = "Retrieve" Content = "Retrieve" HorizontalAlignment = "Left" VerticalAlignment = "Top" Margin = "384,406,0,0" Click = "Retrieve_Click"/> <Button x:Name = "Add" Content = "Add" HorizontalAlignment = "Left" VerticalAlignment = "Top" Margin = "291,406,0,0" Click = "Add_Click"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Name" VerticalAlignment = "Top" Margin = "233,280,0,0" Width = "52"/> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" TextWrapping = "Wrap" VerticalAlignment = "Top" Margin = "289,274,0,0" Width = "370"/> <TextBlock x:Name = "textBlock1" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Age" VerticalAlignment = "Top" Margin = "233,342,0,0" Width = "52"/> <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" TextWrapping = "Wrap" VerticalAlignment = "Top" Margin = "289,336,0,0" Width = "191"/> <TextBlock x:Name = "textBlock2" HorizontalAlignment = "Left" Margin = "290,468,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "324" Height = "131"/> </Grid> </Page>
下面给出了事件和SQLite 数据库的 C# 实现。
using SQLite.Net.Attributes; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPSQLiteDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { string path; SQLite.Net.SQLiteConnection conn; public MainPage(){ this.InitializeComponent(); path = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite"); conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path); conn.CreateTable<Customer>(); } private void Retrieve_Click(object sender, RoutedEventArgs e) { var query = conn.Table<Customer>(); string id = ""; string name = ""; string age = ""; foreach (var message in query) { id = id + " " + message.Id; name = name + " " + message.Name; age = age + " " + message.Age; } textBlock2.Text = "ID: " + id + "\nName: " + name + "\nAge: " + age; } private void Add_Click(object sender, RoutedEventArgs e){ var s = conn.Insert(new Customer(){ Name = textBox.Text, Age = textBox1.Text }); } } public class Customer { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public string Age { get; set; } } }
上述代码编译执行后,会看到如下窗口。
输入姓名和年龄,然后单击添加按钮。
现在单击检索按钮。您将在文本块上看到以下数据。
ID 字段是主键和自动增量字段,在 Customer 类中指定。
[PrimaryKey, AutoIncrement] public int Id { get; set; }
Windows10 Dev – 应用程序通信
应用程序间通信意味着您的应用程序可以与安装在同一设备上的另一个应用程序对话或通信。这不是通用 Windows 平台 (UWP) 应用程序中的新功能,在 Windows 8.1 中也可用。
在 Windows 10 中,引入了一些新的和改进的方法来轻松地在同一设备上的应用程序之间进行通信。两个应用程序之间的通信可以通过以下方式 –
- 一个应用程序使用一些数据启动另一个应用程序。
- 应用程序只是在不启动任何东西的情况下交换数据。
应用间通信的主要优点是您可以将应用程序分成更小的块,这些块可以轻松维护、更新和使用。
准备好您的应用程序
如果您按照下面给出的步骤操作,其他应用程序可以启动您的应用程序。
-
在应用程序包清单中添加协议声明。
-
双击Package.appxmanifest文件,该文件在解决方案资源管理器中可用,如下所示。
-
转到声明选项卡并写下协议的名称,如下所示。
-
下一步是添加激活码,以便应用程序在被其他应用程序启动时可以做出适当的响应。
-
为了响应协议激活,我们需要覆盖激活类的OnActivated方法。因此,在App.xaml.cs文件中添加以下代码。
protected override void OnActivated(IActivatedEventArgs args) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; if (args != null){ Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null){ // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); // Set the default language rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; rootFrame.NavigationFailed += OnNavigationFailed; // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null){ // When the navigation stack isn't restored, navigate to the // first page, configuring the new page by passing required // information as a navigation parameter rootFrame.Navigate(typeof(MainPage), null); } // Ensure the current window is active Window.Current.Activate(); } }
-
要启动应用程序,您可以简单地使用Launcher.LaunchUriAsync方法,该方法将使用此方法中指定的协议启动应用程序。
await Windows.System.Launcher.LaunchUriAsync(new Uri("win10demo:?SomeData=123"));
让我们通过一个简单的示例来理解这一点,其中我们有两个带有ProtocolHandlerDemo和FirstProtocolHandler 的UWP 应用程序。
在此示例中,ProtocolHandlerDemo应用程序包含一个按钮,单击该按钮将打开FirstProtocolHandler应用程序。
下面给出了包含一个按钮的 ProtocolHandlerDemo 应用程序中的 XAML 代码。
<Page x:Class = "ProtocolHandlerDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ProtocolHandlerDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "LaunchButton" Content = " Launch First Protocol App" FontSize = "24" HorizontalAlignment = "Center" Click = "LaunchButton_Click"/> </Grid> </Page>
下面给出的是 C# 代码,其中实现了按钮单击事件。
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace ProtocolHandlerDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); } private async void LaunchButton_Click(object sender, RoutedEventArgs e) { await Windows.System.Launcher.LaunchUriAsync(new Uri("win10demo:?SomeData=123")); } } }
现在让我们看看FirstProtocolHandler应用程序表。下面给出了 XAML 代码,其中使用一些属性创建了一个文本块。
<Page x:Class = "FirstProtocolHandler.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:FirstProtocolHandler" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBlock Text = "You have successfully launch First Protocol Application" TextWrapping = "Wrap" Style = "{StaticResource SubtitleTextBlockStyle}" Margin = "30,39,0,0" VerticalAlignment = "Top" HorizontalAlignment = "Left" Height = "100" Width = "325"/> </Grid> </Page>
覆盖OnActicated的App.xaml.cs文件的 C# 实现如下所示。在App.xaml.cs文件的App 类中添加以下代码。
protected override void OnActivated(IActivatedEventArgs args) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; if (args != null) { Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); // Set the default language rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; rootFrame.NavigationFailed += OnNavigationFailed; // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // When the navigation stack isn't restored navigate to the // first page, configuring the new page by passing required // information as a navigation parameter rootFrame.Navigate(typeof(MainPage), null); } // Ensure the current window is active Window.Current.Activate(); } }
当您在模拟器上编译并执行ProtocolHandlerDemo应用程序时,您将看到以下窗口。
现在,当您单击该按钮时,它将打开FirstProtocolHandler应用程序,如下所示。
Windows 10 开发 – 本地化
Windows 在全球范围内使用,用于各种不同的市场,并针对不同文化、地区或语言的目标受众。本地化是将应用程序资源翻译成应用程序支持的特定文化的本地化版本。
当您仅使用一种语言开发任何应用程序时,这意味着您只是在限制您的业务和客户。如果您想增加客户群,这也将增加您的业务,那么您的应用程序必须在全球范围内可用且可访问。经济高效的产品本地化是接触更多客户的最佳和最经济的方式之一。
在 Windows 10 中,使用resx文件非常容易创建可本地化的应用程序,这是最简单的本地化解决方案。
让我们按照下面提到的所有步骤,借助一个简单的示例来理解这一点。
翻译 UI 资源
您可以将 UI 的字符串资源放入资源 ( resw ) 文件中,而不是将它们直接放入代码或标记中,然后您可以从您的代码或标记中引用这些字符串。按照下面给出的步骤将字符串添加到资源文件中。
-
创建新的通用 Windows 平台 (UWP) 应用程序。
-
在解决方案资源管理器中,右键单击该项目并选择添加 > 新建文件夹。
-
将新文件夹的名称更改为“Strings”。
-
右键单击Strings文件夹并添加一个名为“ en-US ”的新文件夹。这些是特定于语言和国家/地区名称的命名约定,可以在国家语言支持 (NLS) API 参考msdn.microsoft.com页面上找到。
-
右键单击en-US文件夹并选择添加 > 新项目…。
- 将打开以下对话框。
-
选择“资源文件 (.resw)”并单击“添加”按钮。
-
现在让我们转到 XAML 文件并添加具有一些属性的 Hub 控件,如下所示。
<Page x:Class = "UWPLocalizationDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPLocalizationDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub x:Name = "textBlock" x:Uid = "HubControl" Background = "Black" Foreground = "White" Header = "Localization Demo"/> </Grid> </Page>
-
x:Uid = “HubControl”是用于本地化的标识符
-
现在,当上面的代码编译并执行时,您将看到以下窗口。
与 Hub 相关的所有信息,例如 Header、Foreground 和背景颜色都在 XAML 中设置。
-
现在在Strings/en-US文件夹中的Resource.resw文件中添加一些信息,如下所示。
-
您需要将需要本地化文本的每个控件与 . resw文件。你可以通过在你的 XAML 元素上使用x:Uid属性来做到这一点 –
-
x:Uid = “HubControl”用于在resw文件中为标题、前景色和背景色分配一个字符串。
-
-
现在,当您在模拟器上编译和执行应用程序时,您将看到以下窗口。您可以看到标题、前景色和背景色值是从Resources.resw文件中选取的。
-
您可以手动添加其他语言(如法语、德语和日语等)的其他Resource.resw文件,就像我们为英语-美国所做的那样,但微软还提供了多语言应用程序工具包,借助它,您可以轻松地翻译您的Resource.resw 转换为其他语言。
-
转到工具 > 扩展和更新菜单并搜索多语言应用程序工具包。
-
下载并安装此工具包。安装完成后,重新启动 Visual Studio 并打开相同的项目。
-
现在从“工具”>“多语言应用程序工具包”菜单选项启用此工具包。
-
现在您可以添加其他语言的翻译。
-
右键单击解决方案资源管理器中的项目,然后从菜单中选择多语言应用程序工具包 > 添加翻译语言选项。
-
将打开以下翻译语言对话框。您可以选择您想要的任何语言,以针对这些文化本地化您的应用程序。
-
让我们选择德语并单击“确定”按钮。
-
您还可以看到Resources.resw文件是在文件夹Strings\de 中创建的。
-
现在,您将看到在*.xlf文件中添加了另一个MultiLingualResources。双击此文件,这将打开多语言编辑器以检查和验证已翻译的字符串,并在需要时进行一些更改。
-
进行更改并验证背景颜色是否已更改为棕色,并且标题文本是否已正确翻译为德语。
-
如上例,Hub 的背景色从蓝色变为棕色,前景色保持不变。
-
现在打开Resources.resw,它位于Strings\de文件夹内。
-
可以看到这里只提到了两个字符串,因为我们没有在多语言编辑器上更改前景色。
要检查应用程序的本地化版本,请更改机器的文化。要更改机器的文化,请按照给定的步骤操作。
- 让我们转到 PC 设置并选择时间和语言。
-
从左侧窗格中,选择Regions & language并单击Add a language。
-
选择Deutsch German language 如上所示,这将打开另一个对话框。
-
现在选择German (德国)并关闭此对话框。
- 将 Deutsch 设为默认语言。
- 现在执行您的应用程序,它将显示以下窗口。
- 现在,您可以看到应用程序的德语输出。
Windows 10 开发 – 生命周期
从历史上看,Windows 具有用户可以同时运行多个应用程序的环境。用户可以轻松地在不同的应用程序之间切换。此模型不适用于手机或平板电脑设备,因为这些设备的使用通常侧重于单一应用程序。
Windows 8 应用商店应用程序程序员面临的最重大挑战之一是管理和理解应用程序生命周期。如果您一直在构建 Windows 手机应用程序,那么您应该很熟悉其中的大部分内容。
-
在 Windows 8 下,操作系统管理应用程序的生命周期,虽然用户可以终止应用程序,但通常用户打开新应用程序时不会有意终止正在运行的应用程序。
-
适用于 Windows 10 的通用 Windows 平台 (UWP) 解决了这些问题,为桌面用户提供了一些很酷的东西,以便多个应用程序可以以多窗口体验运行。
Windows 应用程序可以在基本级别以三种状态存在,如下所示。
-
跑步
-
暂停
-
终止
-
当用户启动/激活任何应用程序时,它就会进入运行状态。
-
如果用户不使用它并且它不再处于前台,则可以暂停应用程序。
-
从挂起状态,应用程序可以恢复该应用程序或终止操作系统以回收系统资源。
进程状态转换
了解正在运行的应用程序中的进程状态转换非常重要。当用户第一次启动应用程序时,会显示启动画面,然后应用程序开始运行。
该过程可以解释如下 –
-
当应用程序暂停时,您的应用程序有五秒钟的时间来处理该暂停事件。
-
当应用程序暂停时,绝对没有代码运行,也没有分配资源。
-
当它恢复时,会通知应用程序它已恢复。如果您来自暂停状态,则无需采取任何措施。
-
在内存压力下,您的应用程序可能会被终止。
-
请记住,此时您不会收到通知,因此您所做的任何保存都必须在进入暂停应用程序状态时执行。
当应用程序在Running和Suspended状态之间来回转换时,分别触发挂起和恢复事件。
有时,您需要保存数据。然后你必须调用异步方法,如下所示。
Application.Current.Suspending += new SuspendingEventHandler(App_Suspending); async void App_Suspending(Object sender, Windows.ApplicationModel.SuspendingEventArgs e){ // Create a simple setting localSettings.Values["FirstName"] = fName.Text; localSettings.Values["LastName"] = lName.Text; localSettings.Values["Email"] = email.Text; }
Application.Current.Resuming += new EventHandler<Object>(App_Resuming); private void App_Resuming(Object sender, Object e){ fName.Text = localSettings.Values["FirstName"]; lName.Text = localSettings.Values["LastName"]; email.Text = localSettings.Values["Email"]; }
让我们研究一个添加控件的示例,如下面给定的 XAML 文件所示。
<Page x:Class = "UWPLifeCycleDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPLifeCycleDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Details" /> <StackPanel VerticalAlignment = "Top" HorizontalAlignment = "Left" Margin = "12,64,0,0"> <TextBox Header = "First Name" Text = "{Binding FirstName, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <TextBox Header = "Last Name" Text = "{Binding LastName, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <TextBox Header = "Email" Text = "{Binding Email, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <Button Margin = "0,12">Submit</Button> </StackPanel> </Grid> </Page>
下面给出了实现 Suspend 和 Resume 事件的 C# 代码。当前数据将存储在本地设置中的挂起事件中,然后数据将在恢复事件中从本地设置中检索,如下所示。
using System; using System.ComponentModel; using System.Runtime.CompilerServices; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace UWPLifeCycleDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page{ var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; public MainPage() { this.InitializeComponent(); Application.Current.Suspending += new SuspendingEventHandler(App_Suspending); Application.Current.Resuming += new EventHandler<Object>(App_Resuming); } async void App_Suspending(Object sender, Windows.ApplicationModel.SuspendingEventArgs e){ // Create a simple setting localSettings.Values["FirstName"] = fName.Text; localSettings.Values["LastName"] = lName.Text; localSettings.Values["Email"] = email.Text; } private void App_Resuming(Object sender, Object e){ fName.Text = localSettings.Values["FirstName"]; lName.Text = localSettings.Values["LastName"]; email.Text = localSettings.Values["Email"]; } } public abstract class BindableBase : INotifyPropertyChanged { private string _FirstName = default(string); public string FirstName { get { return _FirstName; } set { Set(ref _FirstName, value); } } private string _LastName = default(string); public string LastName { get { return _LastName; } set { Set(ref _LastName, value); } } private string _Email = default(string); public string Email { get { return _Email; } set { Set(ref _Email, value); } } public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged([CallerMemberName]string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public void Set<T>(ref T storage, T value, [CallerMemberName()]string propertyName = null){ if (!object.Equals(storage, value)){ storage = value; RaisePropertyChanged(propertyName); } } } }
上述代码编译执行后,会看到如下窗口。现在编写所需的信息。
让我们转到Lifecycle Events 下拉菜单并选择paused。现在您的应用程序将被暂停,所需的信息将存储在本地设置中。请参阅下面给出的屏幕截图。
现在,当您想要恢复应用程序时,请从生命周期事件菜单中选择恢复选项。
现在您将看到存储的信息是从本地设置中检索的,并且应用程序恢复到挂起时的相同状态。
Windows10 Dev – 后台执行
通用 Windows 平台 (UWP) 引入了新机制,允许应用程序在应用程序不在前台运行时执行某些功能。UWP 还增加了应用程序在后台任务和触发器的后台延长执行时间的能力。后台执行是应用程序生命周期的真正补充。
后台任务的重要功能是 –
-
后台任务由系统或时间事件触发,可以受一个或多个条件的约束。
-
当触发后台任务时,其关联的处理程序运行并执行后台任务的工作。
-
即使注册后台任务的应用程序挂起,后台任务也可以运行。
-
它们是标准应用程序平台的一部分,本质上为应用程序提供了注册系统事件(触发器)的能力。当该事件发生时,它们会在后台运行预定义的代码块。系统触发器包括网络连接或系统时区的变化等事件。
-
后台执行无法保证,因此不适合关键功能和特性。
-
操作系统对可以同时运行的后台任务数量有限制。因此,即使触发触发器并满足条件,任务仍然无法运行。
创建和注册后台任务
创建一个后台任务类并注册它以在您的应用程序不在前台时运行。您可以通过编写实现IBackgroundTask接口的类在后台运行代码。以下示例代码显示了后台任务类的一个非常基本的起点。
public sealed class MyBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance){ // write code } }
您可以按如下方式请求访问后台任务。
var access = await BackgroundExecutionManager.RequestAccessAsync(); switch (access) { case BackgroundAccessStatus.Unspecified: break; case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity: break; case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity: break; case BackgroundAccessStatus.Denied: break; default: break; }
要构建和注册后台任务,请使用以下代码。
var task = new BackgroundTaskBuilder { Name = "My Task", TaskEntryPoint = typeof(BackgroundStuff.MyBackgroundTask).ToString() }; var trigger = new ApplicationTrigger(); task.SetTrigger(trigger); task.Register(); await trigger.RequestAsync();
让我们按照以下所有步骤了解后台任务的简单示例。
-
创建一个新的空白 UWP 项目“UWPBackgroundDemo”并在 XAML 文件中添加一个按钮。
<Page x:Class = "UWPBackgroundDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBackgroundDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "button" Content = "Button" HorizontalAlignment = "Left" Margin = "159,288,0,0" VerticalAlignment = "Top" Click = "button_Click"/> </Grid> </Page>
-
下面给出了注册后台任务的按钮单击事件实现。
using System; using Windows.ApplicationModel.Background; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPBackgroundDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private async void button_Click(object sender, RoutedEventArgs e) { var access = await BackgroundExecutionManager.RequestAccessAsync(); switch (access){ case BackgroundAccessStatus.Unspecified: break; case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity: break; case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity: break; case BackgroundAccessStatus.Denied: break; default: break; } var task = new BackgroundTaskBuilder { Name = "My Task", TaskEntryPoint = typeof(BackgroundStuff.MyBackgroundTask).ToString() }; var trigger = new ApplicationTrigger(); task.SetTrigger(trigger); var condition = new SystemCondition(SystemConditionType.InternetAvailable); task.Register(); await trigger.RequestAsync(); } } }
-
现在创建另一个项目,但这次从菜单中选择 Windows Runtime Component (Universal Windows) 并为此项目命名背景内容。
-
下面给出的是 C# 代码。其中包含MyBackgroundTask类植入,它将运行后台任务。
using Windows.ApplicationModel.Background; using Windows.UI.Notifications; namespace BackgroundStuff { public sealed class MyBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { SendToast("Hi this is background Task"); } public static void SendToast(string message) { var template = ToastTemplateType.ToastText01; var xml = ToastNotificationManager.GetTemplateContent(template); var elements = xml.GetElementsByTagName("Test"); var text = xml.CreateTextNode(message); elements[0].AppendChild(text); var toast = new ToastNotification(xml); ToastNotificationManager.CreateToastNotifier().Show(toast); } } }
-
要在UWPBackgroundDemo项目中访问此项目,请右键单击“解决方案资源管理器”中的“引用”>“添加引用”,然后添加BackgroundStuff项目。
-
现在,让我们转到UWPBackgroundDemo项目的Package.appxmanifest文件,并在声明选项卡中添加以下信息。
-
首先构建Background stuff项目,然后构建并执行UWPBackgroundDemo项目。
-
上述代码编译执行后,会看到如下窗口。
-
当您单击按钮 时,它将运行后台任务并在窗口的右端显示通知。
Windows 10 开发 – 服务
在本章中,我们将了解 UWP 应用如何帮助或为另一个通用 Windows 平台 (UWP) 应用程序提供服务。实际上,本章是对后台执行一章的扩展,是它的一个特例。
-
在 Windows 10 中,应用服务是应用向其他应用提供服务的一种方式或机制。
-
应用服务以后台任务的形式工作。
-
前台应用可以调用另一个应用中的应用服务在后台执行任务。
应用服务类似于 Web 服务,但应用服务在 Windows 10 设备上使用。
通用 Windows 平台 (UWP) 应用程序可以通过各种方式与另一个 UWP 应用程序交互 –
- 使用 LaunchUriAsync 的 URI 关联
- 使用 LaunchFileAsync 进行文件关联
- 使用 LaunchUriForResultsAsync 启动结果
- 应用服务
当两个应用程序都在前台时使用前三种方式,但应用服务在后台任务中使用,在这种情况下,客户端应用程序必须在前台并且可以使用应用服务。
应用程序服务在提供非视觉服务的应用程序中非常有用,例如条形码扫描仪,其中前台应用程序将获取图像并将这些字节发送到应用程序服务以识别条形码。
为了理解所有这些概念,让我们在 Microsoft Visual Studio 2015 中创建一个名为AppServiceProvider的新 UWP 项目。
现在在Package.appmenifest文件中,添加以下信息。
要创建可由前台应用程序调用的应用服务,让我们向解决方案中添加一个名为MyAppService的新Windows 运行时组件项目,因为应用服务是作为后台任务实现的。
在AppServiceProvider项目中添加对MyAppService项目的引用。
现在从MyAppService项目中删除class1.cs文件并添加一个具有清单名称的新类,它将实现IBackgrounTask接口。
所述IBackgrounTask接口只有一个方法“运行”,其需要用于后台任务来实现。
public sealed class Inventory : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { } }
创建后台任务时,调用Run() 方法,当 Run 方法完成时,则终止后台任务。为了保持后台任务,服务请求,代码需要延迟。
应用服务代码位于OnRequestedReceived() 中。在此示例中,库存项目的索引传递给服务,以检索指定库存项目的名称和价格。
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { // Get a deferral because we use an awaitable API below to respond to the message }
下面给出了在 C# 中 Inventory 类的完整实现。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Background; using Windows.Foundation.Collections; namespace MyAppService{ public sealed class Inventory : IBackgroundTask { private BackgroundTaskDeferral backgroundTaskDeferral; private AppServiceConnection appServiceconnection; private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" }; private double[] inventoryPrices = new double[] { 129.99, 88.99 }; public void Run(IBackgroundTaskInstance taskInstance) { this.backgroundTaskDeferral = taskInstance.GetDeferral(); taskInstance.Canceled += OnTaskCanceled; var details = taskInstance.TriggerDetails as AppServiceTriggerDetails; appServiceconnection = details.AppServiceConnection; appServiceconnection.RequestReceived += OnRequestReceived; } private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var messageDeferral = args.GetDeferral(); ValueSet message = args.Request.Message; ValueSet returnData = new ValueSet(); string command = message["Command"] as string; int? inventoryIndex = message["ID"] as int?; if (inventoryIndex.HasValue && inventoryIndex.Value >= 0 && inventoryIndex.Value < inventoryItems.GetLength(0)) { switch (command) { case "Price": { returnData.Add("Result", inventoryPrices[inventoryIndex.Value]); returnData.Add("Status", "OK"); break; } case "Item": { returnData.Add("Result", inventoryItems[inventoryIndex.Value]); returnData.Add("Status", "OK"); break; } default: { returnData.Add("Status", "Fail: unknown command"); break; } } else { returnData.Add("Status", "Fail: Index out of range"); } } await args.Request.SendResponseAsync(returnData); messageDeferral.Complete(); } private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason){ if (this.backgroundTaskDeferral != null) { // Complete the service deferral. this.backgroundTaskDeferral.Complete(); } } } }
让我们通过添加一个新的空白 UWP 项目ClientApp来创建一个客户端应用程序,并在 XAML 文件中添加一个按钮、一个文本框和两个文本块,如下所示。
<Page x:Class = "ClientApp.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ClientApp" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBlock HorizontalAlignment = "Left" Text = "Enter Item No." Margin = "52,40,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "32" Width = "268"/> <Button x:Name = "button" Content = "Get Info" HorizontalAlignment = "Left" Margin = "255,96,0,0" VerticalAlignment = "Top" Click = "button_Click"/> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Margin = "52,96,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "168"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" Margin = "52,190,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "32" Width = "268"/> </Grid> </Page>
下面给出了请求应用服务的按钮单击事件实现。
using System; using Windows.ApplicationModel.AppService; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace ClientApp { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { private AppServiceConnection inventoryService; public MainPage() { this.InitializeComponent(); } private async void button_Click(object sender, RoutedEventArgs e){ // Add the connection. if (this.inventoryService == null) { this.inventoryService = new AppServiceConnection(); this.inventoryService.AppServiceName = "com.microsoft.inventory"; this.inventoryService.PackageFamilyName = "bb1a8478-8005-46869923-e525ceaa26fc_4sz2ag3dcq60a"; var status = await this.inventoryService.OpenAsync(); if (status != AppServiceConnectionStatus.Success) { button.Content = "Failed to connect"; return; } } // Call the service. int idx = int.Parse(textBox.Text); var message = new ValueSet(); message.Add("Command", "Item"); message.Add("ID", idx); AppServiceResponse response = await this.inventoryService.SendMessageAsync(message); string result = ""; if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result = response.Message["Result"] as string; } } message.Clear(); message.Add("Command", "Price"); message.Add("ID", idx); response = await this.inventoryService.SendMessageAsync(message); if (response.Status == AppServiceResponseStatus.Success){ // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result += " : Price = " + "$"+ response.Message["Result"] as string; } } textBlock.Text = result; } } }
要运行此应用程序,您需要在解决方案资源管理器中将ClientApp项目设置为启动项目,然后从Build > Deploy Solution部署此解决方案。
上述代码编译执行后,会看到如下窗口。在应用服务中,我们刚刚添加了两个项目的信息。因此,您可以输入 0 或 1 来获取这些项目的信息。
当您输入 0 并单击按钮时,它将运行 App 服务作为后台任务,并将在textblock上显示项目信息。
Windows 10 开发 – Web 平台
在 Windows 10 中,开发人员很容易创建通用 Windows 平台 (UWP) 应用程序并在该应用程序上托管他们的网站,然后可以将其发布到 Windows 应用商店进行下载。
好处
-
借助 Windows 10 中的这一新功能,Web 开发人员可以轻松地将其网站的组件转换为 Windows 应用程序。
-
但是,所有这些组件仍将远程托管在他们自己的 Web 服务器上。
-
此外,他们还可以访问通用 API,这将允许开发人员访问一些很酷的东西,如通知、相机、日历、Cortana 等。
微软希望这个特性和能力能够吸引更多的开发者为 Windows 10 平台编写应用程序,其中包括。
- 台式机
- 智能手机
- Xbox
- 平板电脑
- HoloLens 和其他设备
目前,此功能只有一个问题,那就是安全性。显然,微软需要尽快解决这个问题。
让我们借助一个示例来了解我们将托管一个网站并将该网站转换为 Windows 应用程序。
按照下面给出的步骤。
-
从File > New > Project创建一个新的通用 Windows项目。
-
从新建项目和对话框的左窗格中选择JavaScript > Windows > Universal选项。
-
从中间窗格中,选择Blank App (Universal Windows)。
-
在名称字段中写入UWPWebApp,然后单击确定按钮。
-
如果您查看解决方案资源管理器窗口,您将看到一些文件和文件夹。
-
删除css、js、WinJS文件夹和default.html文件,因为在这个例子中,我们只是托管一个网站,我们假设所有内容都在远程服务器上。因此,我们不需要大部分本地文件。
-
删除上述文件和文件夹后,现在双击package.appxmanifest文件,您将看到以下窗口。
-
现在通过将起始页字段中的default.html替换为 URL 来指定网站URL。出于演示目的,我们将使用 URL https://www.google.com.pk/网站。
-
现在转到Content URIs选项卡并为您的 Web 应用程序定义规则和访问权限。
-
在 URI 字段中,指定您的网站链接,然后从规则下拉列表中选择包括和从WinRT Access 中选择所有。
-
当您运行此应用程序时,您将在您的应用程序上看到如下所示的 google 起始页。
Windows10 开发人员 – 连接体验
众所周知,在 Windows 10 中,我们可以创建一个可以在多个 Windows 10 设备上执行和运行的应用程序。让我们假设我们有这些不同的设备,我们想让它感觉像是一个应用程序,即使它在不同的设备上运行。
在通用 Windows 平台 (UWP) 中,您可以在所有 Windows 10 设备上运行单个应用程序,并且可以让用户感觉它是一个应用程序。这被称为连接体验。
连接体验的重要特征 –
-
Windows 10 是迈向更加个性化计算时代的第一步,在这个时代,您的应用、服务和内容可以跨设备无缝、轻松地移动。
-
凭借互联体验,您可以轻松共享与该应用程序相关的数据和个人设置,并且可以在所有设备上使用。
在本章中,我们将学习 –
-
这些共享数据或设置将存储在哪里,以便可以在您的设备上用于该应用程序。
-
如何识别用户;同一用户在不同设备上使用相同的应用程序。
Windows 10 向前迈出了大胆的一步。当您使用 Microsoft 帐户 (MSA) 或您的企业或(工作)帐户登录 Windows 10 时,假设 –
-
您可以免费访问 OneDrive for MSA 帐户,并且可以访问 Active Directory (AD) 和 Azure Active Directory (AAD),这是具有企业帐户的云版本。
-
您可以访问不同的应用程序和资源。
-
设备和应用程序处于漫游状态和设置。
在 Windows 10 中漫游
当您登录到 PC 时,您可以设置一些首选项,例如锁定屏幕或背景颜色,或者个性化您的不同类型的设置。如果您有多台运行 Windows 10 的计算机或设备,当您使用同一帐户登录其他设备时,您在一台设备上的首选项和设置将从云端同步。
在 Windows 10 中,当您设置或个性化您的应用程序设置后,这些设置将随 UWP 中可用的漫游 API 漫游。当您在其他设备上再次运行相同的应用程序时,它将首先检索设置并将这些设置应用于该设备上的应用程序。
将漫游数据上传到云端有 100KB 的限制。如果超过此限制,则同步将停止并且将像本地文件夹一样运行。
的RoamingSettings API是公开为字典中的应用程序可以保存数据。
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; // Retrivve value from RoamingSettings var colorName = roamingSettings.Values["PreferredBgColor"].ToString(); // Set values to RoamingSettings roamingSettings.Values["PreferredBgColor"] = "Green";
当RoamingSettings 中的数据更改时,它会触发DataChanged事件,您可以在其中刷新设置。
Windows.Storage.ApplicationData.Current.DataChanged += RoamingDataChanged; private void RoamingDataChanged(Windows.Storage.ApplicationData sender, object args) { // Something has changed in the roaming data or settings }
让我们看一个示例,在该示例中,我们将设置应用程序的背景颜色,这些设置将随 UWP 中可用的漫游 API 漫游。
下面给出了添加不同控件的 XAML 代码。
<Page x:Class = "RoamingSettingsDemo.Views.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:RoamingSettingsDemo.Views" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid x:Name = "MainGrid" Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height = "80" /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Orientation = "Horizontal" VerticalAlignment = "Top" Margin = "12,12,0,0"> <TextBlock Style = "{StaticResource HeaderTextBlockStyle}" FontSize = "24" Text = "Connected Experience Demo" /> </StackPanel> <Grid Grid.Row = "1" Margin = "0,80,0,0"> <StackPanel Margin = "62,0,0,0"> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Choose your background color:" VerticalAlignment = "Top"/> <RadioButton x:Name = "BrownRadioButton" Content = "Brown" Checked = "radioButton_Checked" /> <RadioButton x:Name = "GrayRadioButton" Content = "Gray" Checked = "radioButton_Checked"/> </StackPanel> </Grid> </Grid> </Page>
下面给出了RoamingSettings和不同事件的C# 实现。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The RoamingSettingsDemo Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace RoamingSettingsDemo.Views { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { SetBackgroundFromSettings(); Windows.Storage.ApplicationData.Current.DataChanged += RoamingDataChanged; } protected override void OnNavigatedFrom(NavigationEventArgs e) { Windows.Storage.ApplicationData.Current.DataChanged -= RoamingDataChanged; } private void RoamingDataChanged(Windows.Storage.ApplicationData sender, object args) { // Something has changed in the roaming data or settings var ignore = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () ⇒ SetBackgroundFromSettings()); } private void SetBackgroundFromSettings() { // Get the roaming settings Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; if (roamingSettings.Values.ContainsKey("PreferBrownBgColor")) { var colorName = roamingSettings.Values["PreferBrownBgColor"].ToString(); if (colorName == "Gray") { MainGrid.Background = new SolidColorBrush(Colors.Gray); GrayRadioButton.IsChecked = true; } else if (colorName == "Brown") { MainGrid.Background = new SolidColorBrush(Colors.Brown); BrownRadioButton.IsChecked = true; } } } private void radioButton_Checked(object sender, RoutedEventArgs e){ if (GrayRadioButton.IsChecked.HasValue && (GrayRadioButton.IsChecked.Value == true)) { Windows.Storage.ApplicationData.Current.RoamingSettings. Values["PreferBrownBgCo lor"] = "Gray"; } else { Windows.Storage.ApplicationData.Current.RoamingSettings. Values["PreferBrownBgCo lor"] = "Brown"; } SetBackgroundFromSettings(); } } }
上述代码编译执行后,会看到如下窗口。
让我们选择灰色作为背景颜色并关闭此应用程序。
现在,当您在此设备或任何其他设备上运行此应用程序时,您将看到背景颜色已更改为灰色。这说明应用已经成功检索到RoamingSettings 中的背景颜色变化信息。
Windows 10 开发 – 导航
在通用 Windows 平台 (UWP) 应用程序中,导航是导航结构、导航元素和系统级功能的灵活模型。它为在应用程序、页面和内容之间移动提供了各种直观的用户体验。
在某些情况下,所有内容和功能都可以轻松地放入一个页面中,开发人员无需创建多个页面。然而,在大多数应用程序中,多个页面用于不同内容和功能之间的交互。
当应用程序有多个页面时,开发人员提供正确的导航体验非常重要。
页面模型
通常,在通用 Windows 平台 (UWP) 应用程序中,使用单页导航模型。
重要功能是 –
-
单页导航模型将应用程序的所有上下文以及附加内容和数据维护到一个中央框架中。
-
您可以将应用程序的内容分成多个页面。但是,当从一个页面移动到另一个页面时,您的应用程序会将页面加载到主页面表单中。
-
既不卸载应用程序的主页面,也不卸载代码和数据,这样可以更轻松地管理状态,并在页面之间提供更平滑的过渡动画。
多页面导航还用于在不同页面或屏幕之间导航,而无需担心应用程序上下文。在多页面导航中,每个页面都有自己的一套功能、用户界面和数据等。
多页导航通常用于网站内的网页。
导航结构
在多页面导航中,每个页面都有自己的一组功能、用户界面和数据等。例如,一个照片应用程序可能有一个页面用于拍摄照片,然后当用户想要编辑照片时,它会导航到另一个页面为了维护图像库,它还有另一个页面。
应用程序的导航结构由这些页面的组织方式定义。
以下是在您的应用程序中构建导航的方法 –
等级制度
在这种类型的导航结构中,
-
页面被组织成树状结构。
-
每个子页面只有一个父页面,但一个父页面可以有一个或多个子页面。
-
要访问子页面,您必须通过父页面。
同行
在这种类型的导航中 –
- 页面并排存在。
- 您可以按任何顺序从一页转到另一页。
在大多数多页应用程序中,两种结构同时使用。一些页面被组织为对等页面,而其中一些页面被组织成层次结构。
让我们以包含三个页面的示例为例。
-
创建一个名为UWPNavigation的空白 UWP 应用程序。
-
通过右键单击解决方案资源管理器中的项目并从菜单中选择添加 > 新项选项,再添加两个空白页,这将打开以下对话框窗口。
-
从中间窗格中选择空白页,然后单击添加按钮。
-
现在按照上述步骤再添加一页。
您将在解决方案资源管理器中看到三个页面 – MainPage、BlankPage1和BlankPage2。
下面给出了MainPage的 XAML 代码,其中添加了两个按钮。
<Page x:Class = "UWPNavigation.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this Main Page"/> <Button Content = "Go to Page 1" Margin = "64,131,0,477" Click = "Button_Click"/> <Button Content = "Go to Page 2" Margin = "64,210,0,398" Click = "Button_Click_1"/> </Grid> </Page>
下面给出的是MainPage上两个按钮的 C# 代码,它们将导航到其他两个页面。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e){ this.Frame.Navigate(typeof(BlankPage1)); } private void Button_Click_1(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(BlankPage2)); } } }
空白页 1的 XAML 代码如下所示。
<Page x:Class = "UWPNavigation.BlankPage1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this is page 1"/> <Button Content = "Go to Main Page" Margin = "64,94,0,514" Click = "Button_Click"/> </Grid> </Page>
空白页 1上的按钮单击事件的 C# 代码,它将导航到主页,如下所示。
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class BlankPage1 : Page { public BlankPage1() { this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(MainPage)); } } }
下面给出的是空白页 2的 XAML 代码。
<Page x:Class = "UWPNavigation.BlankPage2" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this is page 2"/> <Button Content = "Go to Main Page" Margin = "64,94,0,514" Click = "Button_Click"/> </Grid> </Page>
下面给出了空白页 2上按钮单击事件的 C# 代码,它将导航到主页。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class BlankPage2 : Page { public BlankPage2(){ this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(MainPage)); } } }
上述代码编译执行后,会看到如下窗口。
当您单击任何按钮时,它将导航到相应的页面。让我们点击转到第 1页,将显示以下页面。
当您单击“转到主页”按钮时,它将导航回主页。
Windows 10 开发 – 网络
如今,您将看到许多应用程序,它们以某种方式与网络上的 Web 服务或其他设备集成。获取在线天气内容、最新消息、聊天或点对点游戏是使用网络服务的一些示例。这些应用程序是使用各种网络 API 构建的。在 Windows 10 中,网络 API 在速度和内存性能以及它们为开发人员提供的功能和灵活性方面得到了改进。
能力
为了联网,您必须向应用清单添加适当的功能元素。如果您的应用程序清单中未指定网络功能,则您的应用程序将没有网络功能,并且任何连接到网络的尝试都将失败。
以下是最常用的网络功能。
S.No. | 能力和描述 |
---|---|
1 |
internetClient 提供对 Internet 和公共场所网络(如机场和咖啡店)的出站访问。大多数需要访问 Internet 的应用程序都应使用此功能。 |
2 |
internetClientServer 为应用程序提供来自 Internet 和公共场所(如机场和咖啡店)网络的入站和出站网络访问权限。 |
3 |
privateNetworkClientServer 在用户信任的地方(例如家庭和工作场所)为应用程序提供入站和出站网络访问权限。 |
要在您的应用清单文件中定义一项或多项功能,请查看下图。
通用 Windows 平台 (UWP) 通过针对以下目标包含大量网络 API –
- 查询设备的连接状态并连接对端设备。
- 与 REST Web 服务通信和
- 在后台下载大型媒体文件
网络技术
在通用 Windows 平台 (UWP) 中,开发人员可以使用以下网络技术,这些技术可以在许多不同的情况下使用。
插座
当您想使用自己的协议与另一台设备进行通信时,将使用套接字。
-
作为通用 Windows 平台 (UWP) 应用程序开发人员,您可以使用Windows.Networking.Sockets和Winsock与其他设备进行通信。
-
Windows.Networking.Sockets具有作为现代 API 的优势,专供 UWP 开发人员使用。
-
如果您使用跨平台网络库或其他现有的 Winsock 代码,请使用Winsock API。
以下代码显示了如何创建套接字侦听器。
try { //Create a StreamSocketListener to start listening for TCP connections. Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener(); //Hook up an event handler to call when connections are received. socketListener.ConnectionReceived += SocketListener_ConnectionReceived; //Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use. await socketListener.BindServiceNameAsync("1337"); } catch (Exception e) { //Handle exception. }
以下代码显示了SocketListener_ConnectionReceived事件处理程序的实现。
private async void SocketListener_ConnectionReceived( Windows.Networking.Sockets.StreamSocketListen er sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args){ //Read line from the remote client. Stream inStream = args.Socket.InputStream.AsStreamForRead(); StreamReader reader = new StreamReader(inStream); string request = await reader.ReadLineAsync(); //Send the line back to the remote client. Stream outStream = args.Socket.OutputStream.AsStreamForWrite(); StreamWriter writer = new StreamWriter(outStream); await writer.WriteLineAsync(request); await writer.FlushAsync(); }
网络套接字
该网页套接字协议提供了一个客户端,并通过Web服务器之间的快速,安全的双向通信。通用Windows平台(UWP)开发人员可以使用MessageWebSocket和StreamWebSocket类与支持WebSocket协议服务器连接。
重要功能是 –
-
在 WebSocket 协议下,数据通过全双工单套接字连接立即传输。
-
它允许从两个端点实时发送和接收消息。
-
WebSockets非常适用于实时游戏,即时社交网络通知和最新信息显示(游戏统计数据)需要安全并使用快速数据传输。
以下代码显示了如何在安全连接上发送和接收消息。
MessageWebSocket webSock = new MessageWebSocket(); //In this case we will be sending/receiving a string so we need to set the MessageType to Utf8. webSock.Control.MessageType = SocketMessageType.Utf8; //Add the MessageReceived event handler. webSock.MessageReceived += WebSock_MessageReceived; //Add the Closed event handler. webSock.Closed += WebSock_Closed; Uri serverUri = new Uri("wss://echo.websocket.org"); try { //Connect to the server. await webSock.ConnectAsync(serverUri); //Send a message to the server. await WebSock_SendMessage(webSock, "Hello, world!"); } catch (Exception ex) { //Add code here to handle any exceptions }
以下代码显示了事件实现,它将从连接的WebSocket接收一个字符串。
//The MessageReceived event handler. private void WebSock_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args){ DataReader messageReader = args.GetDataReader(); messageReader.UnicodeEncoding = UnicodeEncoding.Utf8; string messageString = messageReader.ReadString( messageReader.UnconsumedBufferLength); //Add code here to do something with the string that is received. }
客户端
HttpClient和Windows.Web.Http命名空间 API 为开发人员提供使用 HTTP 2.0 和 HTTP 1.1 协议发送和接收信息的能力。
它可用于 –
- 与 Web 服务或 Web 服务器通信。
- 上传或下载一些小文件。
- 通过网络流式传输内容。
以下代码显示如何使用Windows.Web.Http.HttpClient和Windows.Web.Http.HttpResponseMessage发送 GET 请求。
//Create an HTTP client object Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient(); //Add a user-agent header to the GET request. var headers = httpClient.DefaultRequestHeaders; //The safe way to add a header value is to use the TryParseAdd method and verify the return value is true, //especially if the header value is coming from user input. string header = "ie"; if (!headers.UserAgent.TryParseAdd(header)) { throw new Exception("Invalid header value: " + header); } header = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"; if (!headers.UserAgent.TryParseAdd(header)) { throw new Exception("Invalid header value: " + header); } Uri requestUri = new Uri("http://www.contoso.com"); //Send the GET request asynchronously and retrieve the response as a string. Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage(); string httpResponseBody = ""; try { //Send the GET request httpResponse = await httpClient.GetAsync(requestUri); httpResponse.EnsureSuccessStatusCode(); httpResponseBody = await httpResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message; }
Windows 10 开发 – 云服务
作为开发人员,您可能需要桌面上可用的数据以外的数据。云服务可以帮助您访问这些数据。本章让您更好地了解您可能需要的云服务。
Microsoft 提供了一个云计算平台和基础结构,称为Microsoft Azure,您可以在其中构建、部署和管理所有应用程序和服务。
Azure 于 2010 年 2 月 1 日首次发布,名为 Windows Azure。后来它于 2014 年 3 月 25 日更名为 Microsoft Azure。
它同时提供PaaS 和 IaaS服务,并支持许多不同的编程语言、工具和框架,包括 Microsoft 特定的和第三方软件和系统。
微软已经在 Windows 10 中升级了云服务。微软帐户集成是在 Windows 8 中引入的,虽然OneDrive自 2007 年就已经存在。对于 Windows 10,这两项服务都更新了集成度和新功能,吸引了更多用户。
微软帐户
您可以通过 Microsoft 帐户使用 Microsoft 的 Azure 云产品。当然,它不是免费的,但您可以免费试用 30 天。
当您第一次设置一台装有 Windows 10 的机器并使用 Microsoft 帐户登录时,您可以使用相同的帐户进行 Microsoft Azure 订阅。要注册 Microsoft Azure,请单击此处https://azure.microsoft.com/。
订阅 Microsoft Azure 后,请转到 Azure 门户https://portal.azure.com/。您将看到以下页面。
您可以存储在数据库中,使用虚拟机等。您还可以构建和托管移动应用程序的后端。
让我们按照下面提到的步骤,通过一个例子来试试这个。
-
单击左侧窗格中的新建选项。
-
选择Web &plus Mobile > Mobile App并为您的 Web 应用程序命名。
-
提交和部署您的应用程序需要一些时间。完成此过程后,您将看到以下页面。在这里,您可以选择不同类型的移动应用程序,例如 Windows(C#)、iOS Android 等。
-
因为,我们谈论的是 Windows 10,所以选择 Windows (C#),这将打开以下页面。
-
在这里,您可以看到两个下载选项。这些是示例项目,您可以简单地在 Visual Studio 中下载和构建,然后您可以轻松地发布到 Microsoft Azure。
-
让我们下载第一个,它是一个服务器项目。它是一个 zip 文件。
-
下载完成后,解压并在 Visual Studio 中打开。
-
现在,构建这个应用程序。如果列出了一些错误,则重新构建它。
-
运行应用程序。您将看到以下网页,该网页现在位于 localhost 上。
-
现在要在云上托管此应用程序,请右键单击“解决方案浏览器”中的“项目”选项,如下所示。
-
从菜单中选择发布选项。您将看到以下对话框。
-
选择第一个选项 – Microsoft Azure Web Apps。将打开以下对话框。
-
现在单击菜单中的添加帐户选项以添加 Microsoft Azure 帐户。
-
指定您的凭据并单击登录。将打开以下对话窗口。
-
登录后,从Existing Web Apps菜单中选择您的应用程序,然后单击Ok。
-
下面显示的对话框显示了一些与您的应用程序相关的信息,例如名称、服务器名称、URL 等。
-
现在,单击验证连接按钮。验证后,单击“发布”按钮,您将看到您的应用程序现在托管在Microsoft Azure 上。
Windows 10 开发 – 动态磁贴
在本章中,我们将讨论通过磁贴与用户的交互。它是 Windows 10 的标志性部分。磁贴显示在“开始”屏幕和“开始”菜单上。换句话说,它是一种应用程序图标资产,它以多种形式出现在整个 Windows 10 操作系统中。它们是通用 Windows 平台 (UWP) 应用的名片。
瓷砖解剖
瓷砖有三种状态。
-
基本状态– 开始磁贴的基本组件由背板、图标和应用程序标题组成。
-
半实时状态– 与基本磁贴相同,唯一的区别是徽章是一个数字,可以显示 0-99 的数字。
-
实时状态– 此图块包含半实时状态图块的所有元素,还显示额外的内容板块,您可以在其中放置任何您想要的内容,例如照片、文本等。
更新瓷砖
有四种方法可以更新磁贴。
-
Scheduled – 您可以使用ScheduledTileNotification设置模板和时间。
-
Periodic – 当从 URI 中检索信息时,您可以指定在该时间段后提取信息的时间,例如 30 分钟、1 小时、6 小时。等等。
-
本地– 本地可以从您的应用程序更新;无论是从前台还是后台应用程序。
-
Push – 通过从服务器推送信息从服务器更新。
要创建磁贴,请按照给定的代码进行操作。
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Text01); var tileAttributes = tileXml.GetElementsByTagName("text"); tileAttributes[0].AppendChild(tileXml.CreateTextNode("Hello")); var tileNotification = new TileNotification(tileXml); TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
更新徽章非常简单,因为它只是一个数字,您可以设置徽章的值,如下所示。
var type = BadgeTemplateType.BadgeNumber; var xml = BadgeUpdateManager.GetTemplateContent(type); var elements = xml.GetElementsByTagName("badge"); var element = elements[0] as Windows.Data.Xml.Dom.XmlElement; element.SetAttribute("value", "7"); var updator = BadgeUpdateManager.CreateBadgeUpdaterForApplication(); var notification = new BadgeNotification(xml); updator.Update(notification);
让我们在 Visual Studio 中创建一个新的 UWP 项目。
-
您将在解决方案资源管理器的Assets文件夹下看到不同的 png 文件。
-
让我们在包清单中定义一个默认磁贴及其图像。
-
双击package.appxmanifest。这将打开清单编辑器窗口。
-
选择视觉资产选项卡。
-
您可以选择具有任何指定尺寸的应用程序磁贴的图像和图标。在平铺图像和徽标下,为所有徽标提供默认图像,例如
- 方形 71×71 徽标
- 方形 150×150 徽标
- 方形 310×310 徽标
- 商店标志
-
当您执行应用程序然后转到开始屏幕时,您将看到应用程序的磁贴。
Windows 10 开发 – 共享合同
在本章中,我们将学习如何在应用程序之间共享数据。用户经常会遇到他们很高兴与某人分享或在其他应用程序中使用的信息。如今,用户希望使用技术与其他人联系和分享。
用户可能想要分享 –
- 与他们的社交网络的链接
- 将图片复制到报告中
- 上传文件到云存储
今天的应用程序需要确保它们使用的数据也可供用户共享和交换。共享是一种轻量级功能,可以轻松添加到您的 UWP 应用程序中。应用程序可以通过多种方式与其他应用程序交换数据。
在 UWP 应用中,可以通过以下方式支持共享功能;
-
首先,应用程序可以是提供用户想要共享的内容的源应用程序。
-
其次,应用程序可以是用户选择作为共享内容目的地的目标应用程序。
-
应用程序也可以是源应用程序和目标应用程序。
分享内容
从应用程序(源应用程序)共享内容非常简单。要执行任何共享操作,您将需要DataPackage类对象。该对象包含用户想要共享的数据。
DataPackage对象中可以包含以下类型的内容–
- 纯文本
- 统一资源标识符 (URI)
- HTML
- 格式化文本
- 位图
- 文件
- 开发者定义的数据
在共享数据时,您可以包含一种或多种上述格式。要在您的应用程序中支持共享,您首先需要获取DataTransferManager类的实例。
然后它将注册一个事件处理程序,每当发生DataRequested事件时都会调用该处理程序。
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView(); dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.ShareTextHandler);
当您的应用程序接收到DataRequest对象时,您的应用程序就准备好添加用户想要共享的内容。
private void ShareTextHandler(DataTransferManager sender, DataRequestedEventArgs e){ DataRequest request = e.Request; // The Title is mandatory request.Data.Properties.Title = "Share Text Example"; request.Data.Properties.Description = "A demonstration that shows how to share text."; request.Data.SetText("Hello World!"); }
您的应用程序共享的任何内容都必须包含两个属性 –
- Title 属性,这是强制性的,必须设置。
- 内容本身。
接收共享内容
如果您希望您的应用程序可以接收共享内容,那么您需要做的第一件事就是声明它支持Share Contract。声明后,系统会让您的应用程序可以接收内容。
添加对股票合约的支持 –
-
双击package.appmanifest文件。
-
转到声明选项卡。从可用声明列表中选择共享目标,然后单击添加按钮。
-
如果您希望您的应用程序接收任何类型的文件作为共享内容,那么您可以指定文件类型和数据格式。
-
要指定您支持的数据格式,请转至声明页面的数据格式部分,然后单击新增。
-
键入您支持的数据格式的名称。例如,“文本”。
-
要指定您支持的文件类型,请在“声明”页面的“支持的文件类型”部分中,单击“新增”。
-
键入您要支持的文件扩展名,例如.pdf
-
如果要支持所有文件类型,请选中SupportsAnyFileType框。
-
当用户选择您的应用程序作为共享数据的目标应用程序时,将触发OnShareTargetActivated事件。
-
您的应用程序需要处理此事件以处理用户想要共享的数据。
protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args) { // Code to handle activation goes here. }
-
用户想要与任何应用程序共享的所有数据都包含在ShareOperation对象中。您还可以检查它包含的数据的格式。
下面给出的是处理纯文本格式的共享内容的代码片段。
ShareOperation shareOperation = args.ShareOperation; if (shareOperation.Data.Contains(StandardDataFormats.Text)) { string text = await shareOperation.Data.GetTextAsync(); // To output the text from this example, you need a TextBlock control // with a name of "sharedContent". sharedContent.Text = "Text: " + text; }
让我们看一个简单的例子,创建一个新的 UWP 项目,它将共享一个网络链接。
下面给出的是 XAML 代码,其中使用一些属性创建按钮。
<Page x:Class = "UWPSharingDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPSharingDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Orientation = "Vertical"> <TextBlock Text = "Share Web Link" Style = "{StaticResource HeaderTextBlockStyle}" Margin = "30"></TextBlock> <Button Content = "Invoke share contract" Margin = "10" Name = "InvokeShareContractButton" Click = "InvokeShareContractButton_Click" ></Button> </StackPanel> </Grid> </Page>
下面给出了实现按钮单击事件和 URI 共享代码的 C# 代码。
using System; using Windows.ApplicationModel.DataTransfer; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPSharingDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { DataTransferManager dataTransferManager; public MainPage() { this.InitializeComponent(); dataTransferManager = DataTransferManager.GetForCurrentView(); dataTransferManager.DataRequested += dataTransferManager_DataRequested; } void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { Uri sharedWebLink = new Uri("https://msdn.microsoft.com"); if (sharedWebLink != null) { DataPackage dataPackage = args.Request.Data; dataPackage.Properties.Title = "Sharing MSDN link"; dataPackage.Properties.Description = "The Microsoft Developer Network (MSDN) is designed to help developers write applications using Microsoft products and technologies."; dataPackage.SetWebLink(sharedWebLink); } } private void InvokeShareContractButton_Click(object sender, RoutedEventArgs e) { DataTransferManager.ShowShareUI(); } } }
当上面的代码编译执行后,你会在模拟器上看到如下页面。
单击该按钮时,它将提供在哪个应用程序上共享的选项。
单击消息,将显示以下窗口,您可以在其中将链接发送给任何人。
Windows 10 Dev – 移植到 Windows
在本章中,我们将学习如何将您现有的 Windows 8.1 应用程序移植到通用 Windows 平台 (UWP)。您可以创建一个 Windows 10 应用程序包,您的客户可以将其安装到所有类型的设备上。
将您的应用程序移植到 Windows 10 UWP 后,您的应用程序将受益于 –
- 令人兴奋的新硬件
- 巨大的变现机会
- 一个现代的 API 集,
- 自适应 UI 控件,
- 自适应设计和代码
- 一系列输入方式,例如鼠标、键盘、触摸和语音。
将 Windows 8.x 项目移植到 UWP 项目
有两个选项可以将现有的 Windows 8.x 应用程序移植到通用 Windows 平台 (UWP)。
选项 1 – 一种是在 Visual Studio 中创建一个新的 Windows 10 项目并将您的文件复制到其中。
选项 2 – 另一个选项是编辑现有项目文件的副本,包括应用程序包清单。
下面给出了使用第一个选项时的主要步骤。
-
启动 Microsoft Visual Studio 2015 并创建一个名为UWPBookStore的新空白应用程序 (Windows Universal) 项目。
-
您的新项目将构建一个可在所有设备系列上运行的应用程序包(一个 appx 文件)。
-
在您的 Universal 8.1 应用程序项目中,确定您想要重用的所有源代码文件和视觉资产文件。下面显示的是一个示例应用程序,其中包含三个项目。一个用于 Windows,第二个用于移动,第三个是 Windows 和移动的共享项目。
-
在手机上运行此应用程序后,您将看到以下窗口。
-
运行窗口应用程序后,您将看到以下应用程序。
- 现在,打开新创建的 UWP 项目应用程序
-
从共享项目中,复制包含书籍封面图像 (.png) 文件的文件夹Assets\CoverImages。同时复制ViewModel文件夹和MainPage.xaml并替换目标中的文件。
-
从 Windows 项目中,复制BookstoreStyles.xaml。此文件中的所有资源键都将在 Windows 10 应用程序中解析。等效的WindowsPhone文件中的某些文件不会。
-
在解决方案资源管理器中,确保将显示所有文件切换为ON。
-
选择您复制的文件,右键单击它们,然后单击包含在项目中,如下所示。
-
这将自动包括它们的包含文件夹。然后,您可以根据需要将“显示所有文件”切换为“关闭”。
-
现在,您的项目结构在解决方案资源管理器中将如下所示。
-
编辑您刚刚复制的源代码和标记文件,并将对Bookstore1_81命名空间的任何引用更改为UWPBookStore命名空间。
-
最简单的方法是使用替换文件功能替换名称空间。视图模型中不需要更改代码。
-
现在,当执行上述代码时,您可以在本地机器和移动设备上运行它,如下所示。
现在,第二个选项是编辑现有项目文件的副本,包括应用程序包清单。从 Windows/phone 8.x 移植到 Windows 10 时,项目文件和package.appmanifest文件需要进行一些修改。
Microsoft 提供了 UWP 项目升级实用程序,这在移植您现有的应用程序时非常有用。该实用程序可以从github.com下载。
我们建议您逐步按照上述示例进行操作,以便更好地理解。