随着 Windows 10 发布的,未来 Windows 平台都是统一开发模型,可以只写一个 Appx 包,就可以同时部署到

Windows/ Windowsw Phone/ Tablet /xbox ..平台上了,我们几个 Windows 组的同事也是摩拳擦掌,希望写一

个用户体验很好的客户端。

  看了一下 MSDN 最新发布的文档和视频教程,这里作为笔记,大概总结了一下在 Windows 10上,针对 Windows 8.1

和 WP 上的一些技术更新。

贴一张视频里面聚合的路线图:

Windows 10 开发人员预览版中的新增功能

文档内容有点长,下面截取了几处要点翻译了一下:

1)通过 Windows Universal Platform(UAP)统一的 API (Windows Runtime)和一些响应式的 UI 控件,

可以让你只写一个 app ,便可以安装到各种设备上。

2)PC 运行的是桌面操作系统,基于传统的桌面家族。手机、平板等设备,运行的是 mobile 操作系统,基于的是移动

设备家族。

3) Windows 10 提供了新的 universal 控件,导航面板 和开发工具来帮助你面向多种设备进行开发。例如,你可以利用

多种不同屏幕的分辨率来适配你的手机或者电脑的 UI。

4)Windows Phone 上的 Pivot 控件,现在提供给了 universal 设备上

5)在 XAML 页面可以使用 StateTriggers 来触发页面的 visual state 变换。它可以通过窗口尺寸的变化,来直接改变布局、元素

的属性,而不需要在 C# 页面写逻辑进行 VisualStateManager 进行管理。 (类似于 Web 上 CSS 中的 @media ,来实现响应式布局)

6) 一个新的 UI 共享代码的方式,XAML 文件可以共享一个单独的 code-behind 文件了。

7)在选择目标设备的SDK 时,可以直接通过 “项目” -> “引用” 的方式直接添加(与引用类库类似)。添加目标设备的 SDK(选择 Project > Add Reference >

Universal App Platform > Extensions 添加相应的 SDK)。

8)使用这个方法 ApiInformation.IsApiContractPresent (Windows.Foundation.Metadata.ApiInformation class)检测 api 是否支持,

不仅仅是使用条件编译了。因为有的 api 只有个别设备可以使用,例如,手机上的相机实体按键 api。

下面一些内容翻译自视频教程里面的 ppt。

1、Win 8.1 工程 -> Win 10 工程的调整

1)  App 生命周期、后台任务、Tiles 和 toasts 完全一样

2)  UAP  APIs 是 Windows 8.1 WinRT  APIs 的超集 (UAP : universal app platform)

3)  可以使用适应性代码(adaptive  code)判断运行的平台,以替换预编译语句:

例如,之前使用:

#if  WINDOWS_PHONE_APP

      // wp 平台的 api 调用

#elif  WINDOWS_APP

      // win pad 平台的 api 调用

#endif

可以替换为  ApiInformation 类进行判断:

// 判断是否是具有实体按键(Back键、Camera 键..)
if(Windows.Foundation.Metadata.Apilnformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
// Windows phone 的相关 api
}

// Windows.Foundation.Metadata.ApiInformation 类提供的静态方法:
// IsApiContractPresent
// IsEnumNamedValuePresent
// IsEventPresent
// IsMethodPresent
// IsPropertyPresent
// IsReadOnlyPropertyPresent
// IsTypePresent
// IsWriteablePropertyPresent

4) 一些 APIs 被弃用了( 比如 phone 8.1 的文件选择  …AndContinue APIs)

5)  桌面右侧的 Charms 被移出了,所以 app 必须提供 UI 来加载 Settings、Share 和 Search。

  相关代码逻辑和之前完全一样,不需要修改

5)  替换一些有的工程没有定义的系统样式:比如: PhoneAccentBrush

6)  创建一个响应式的 UI:

Phone/narrow view:

small landscape view:

large landscape view:

8)  添加了新控件:Relative Panel、SplitView(Splitview.Content 的属性有意设置为 Frame)

就像 Windows10  上面的 “计算器”,就是 SplitView控件。在单击左上角的 “汉堡包” 按钮,弹出切换菜单:

Win pad 和 win phone 商店里的 Xbox One  SmartGlass 猜测是一个 UAP 包了,在 phone 上的效果:

2、编译指令

// C# Syntax
#if WINDOWS_PHONE_APP
    Windows.Phone.UI.Input.HardwareButtons.BackPressed += this.HardwareButtons_BackPressed;
#endif
//  C++ Syntax
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
_backPressedEventToken = HardwareButtons::BackPressed += ref new EventHandler<BackPressedEventArgs^> (this,&NavigationHelper::HardwareButton_BackPressed);
#endif

3、支持的平台的 SDK,可以直接通过项目引用进行添加:

4、Segoe  MDL2 字体图标资源,更丰富的图标字体可以使用:

前段时间,写过图标资源的文章: 02、Universal app 中按钮图标使用

5、Visual State 可以使用 setters 和 triggers 直接在 XAML 中进行样式的属性的赋值。类似于

Web 上的 CSS媒体查询语法(比如,@media (min-width:800px) and (max-width:1200px) { ... })。

从而不需要再 C# 页面通过 VisualStateManager 进行视图状态的切换。例如下面,当窗口大于 600px 时,

StackPanel 对象为横向布局:

<VisualState x:Name="wideState">
<VisualState.Setters>
<Setter Target="myPanel.Orientation" Value="Horizontal" />
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600"/>
</VisualState.StateTriggers>
</VisualState>

触发器的参数(Trigger types):

  MinWindowWidth

  MinWindowHeight

6、App 与 App 的通信:

1)在 Windows 8.1 时:URI  和 Protocol Activation/Share Contract

2)在 Windows10 UAP:

  a) 启动一个指定的 app :

var options = new LauncherOptions();
options.TargetApplicationPackageFamilyName = "24919.InstapaperIt";
var launchUri = new Uri("instapaper:?AddUrl=http%3A%2F%2Fbing.com");
await Launcher.LaunchUriAsync(launchUri, options);

  b) 向另一个 app 发送数据;通过向另一个app 发送一个文件 token 的方式,以

向另一个 app 传递自己的文件:

var options = new LauncherOptions();
options.TargetApplicationPackageFamilyName = "24919.InstapaperIt"; var token = SharedStorageAccessManager.AddFile(gpxFile); ValueSet inputData = new ValueSet();
inputData.Add("Token", token); var launchUri = new Uri("instapaper:?AddUrl=http%3A%2F%2Fbing.com");
await Launcher.LaunchUriAsync(launchUri, options, inputData);

  c) Launch  for Results:启动另一个 app,并获得其返回结果:

// 一个 app
var options = new LauncherOptions();
options.TargetApplicationPackageFamilyName = "24919.Instap";
var launchUri = new Uri("instapaper:?AddUrl=http%3A%2F%2Fbing.com");
await Launcher.LaunchUriForResultsAsync(launchUri, options, data); // 另一个 app,把结果存到 ValueSet 字典中,返回
var resultData = new ValueSet();
resultData.Add("Result", value);
operation.ProtocolForResultsOperation.ReportCompleted(resultData);

  d) 判断当前设备上是否有指定 app (Query URI Support. Discover if app already installed to handle a Uri):

// 判断当前设备上,是否有 app 声明了instapaper 启动协议名称
var queryUri = new Uri("instapaper:");
await Launcher.QueryUriSupportAsync(queryUri, LaunchUriType.LaunchUri); // 判断当前设备上,是否有 app 声明了instapaper 启动协议名称,并且它的 pfn 为 "24919.InstapaperIt" 的指定app
var queryUri = new Uri("instapaper:");
string packageFamilyName = "24919.InstapaperIt";
await Launcher.QueryUriSupportAsync(queryUri, LaunchUriType.LaunchUriForResults, packageFamilyName);

e) 来自同一个发布者(同一个开发者账号)的多个 app,可 Share 同一个存储文件夹 和设置(files and settings)。

  需要在 app 的清单件中声明一个子文件夹,当系统安装 app 时,会自动创建的:

<Package>
<Extensions>
<Extension Category="windows.publisherCacheFolder">
<PublisherCacheFolder>
<Folder Name="folder1">
</PublisherCacheFolder>
</Extension>
</Extensions>
</Package>

  在 app 中获取这个文件夹:

// 获取这个共享的文件夹
Windows.Storage.ApplicationData.Current.GetPublisherCacheFolder("folder1"); // 清空共享文件夹
Windows.Storage.ApplicationData.Current.ClearPublisherCacheFolderAsync();

  e) App Services:通过后台任务的方式,一个app 可以作为一个本地轻量级的 Web Service

供其它 app 调用。

7、Drag 和 drop

在以前的 XAML 上,拖、拽操作比较局限,只有特定控件(GridView、ListView)有拖拽事件:

<GridView
AllowDrop="true"
DragEnter="contactGridView_DragEnter"
DragLeave="contactGridView_DragLeave"
DragOver="contactView_DragOver"
Drop="contactGridView_Drop"/>

在  UAP 上添加了新的拖、拽 API,可以实现 app 之间的拖放,比如:

1)ListViewBase.DragItemsCompleted

2)UIElement.DragAsync()

3)扩展的  DragEventArgs 参数

8、编译时的数据绑定

XAML 中的 Data Binding 会影响性能,动态类型和反射是部分原因。解决方案是编译时(Compile-time binding)

的绑定。优点是全面快速的实例化,高效的 change 侦测和 UI 更新,编译时错误(Compile-time errors)

<!--示例-->
<ListView ItemsSource="{x:Bind Groups}" >
<ListView.ItemTemplate>
<DataTemplate TargetType="data:BookItem" >
<TextBlock Text="{x:Bind Book.Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

9、Transform 3D, 很像 CSS 中的 “preserve-3d”

Transform 3D 不会影响子元素的   transforms

1)现有的变换属性(Composite transform):

  Translate Transform (move)

  Scale Transform (size)

  Rotate Transform (angle)

  Skew Transform (shape)

  Render Origin

利用 Projection 属性(Rotate  X/Y/Z) 模拟 3D 效果

2) UAP 中添加了新属性 UIElement.Transform3D:

容器:

Container.PerspectiveTransform3D

  Depth

  OffsetX

  OffsetY

子元素:

Child.CompositeTransform3D

  Rotation

  Scale

  Translate

<Grid Width="300" Height="200">

     <Grid.Transform3D>
<PerspectiveTransform3D OffsetX="-150" OffsetY="-100" Depth="1000" />
</Grid.Transform3D> <Grid Background="Red">
<Grid.Transform3D>
<CompositeTransform3D RotationY="30" TranslateZ="1"/>
</Grid.Transform3D>
</Grid> <Grid Background="Blue">
<Grid.Transform3D>
<CompositeTransform3D RotationX="-30" TranslateZ="-1"/>
</Grid.Transform3D>
</Grid>
</Grid>

10、 App Services:

1) UAP 提供了很多 API 来使 app 之间互相通信:

  Windows.ApplicationModel.Contacts

  Windows.ApplicationModel.Email

  Windows.System.Launcher.LaunchUriAsync 启动h settings, maps, store 等…

  其它…

2)UAP 允许 app 之间互相通信:

  · Uri 关联,使用 LaunchUriAsync 启动

  ·  File 关联,使用 LaunchFileAsync 启动

  · Launch 并获取结果,使用 LaunchUriForResultsAsync

  · App Services:用来作为灵活、轻量级的,类似于 web REST 服务:

    a、简单的请求、响应消息 api

    b、以 string-keyed 形式(ValueSet 类型) 数据包传递

    c、易于使用和多个不同的载荷

3)App Services – Client 示例:

AppServiceConnection connection = new AppServiceConnection();
connection.AppServiceName = "microsoftDX-appservicesdemo";
connection.PackageFamilyName = "24919ArunjeetSingh.InstapaperIt"; AppServiceConnectionStatus connectionStatus = await connection.OpenAsync();
if (connectionStatus == AppServiceConnectionStatus.Success)
{
//向服务端发送数据
var message = new ValueSet();
message.Add("Command", "CalcSum");
message.Add("Value1", Int32.Parse(Value1.Text));
message.Add("Value2", Int32.Parse(Value2.Text)); // 发送消息并等待响应
AppServiceResponse response = await connection.SendMessageAsync(message);
if (response.Status == AppServiceResponseStatus.Success)
{
int sum = (int)response.Message["Result"];
new MessageDialog("Result=" + sum).ShowAsync();
}
}
else
{
//如果没有 app service 端,则指导用户下载 app service 端
}

App Services – Service:

namespace AppServicesDemoTask
{
// 需要继承 IBackgroundTask 接口
public sealed class AppServiceTask : IBackgroundTask
{
private static BackgroundTaskDeferral _serviceDeferral; public void Run(IBackgroundTaskInstance taskInstance)
{
// 注册当前后台任务的 取消事件
taskInstance.Canceled += TaskInstance_Canceled; // 获得任务实例的 deferal 对象
_serviceDeferral = taskInstance.GetDeferral(); var appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (appService.Name == "microsoftDX-appservicesdemo")
{
// 可以添加调用 app 的合法性验证 ValidateCaller(appService.CallerPackageFamilyName) ??
appService.AppServiceConnection.RequestReceived += RequestReceived;
}
} ...   private async void RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
  {
   var message = args.Request.Message;     // 服务端使用 Command 参数,作为 client 调用的操作
   string command = message["Command"] as string;
   switch (command)
   {
   case "DoIt": {
   var messageDeferral = args.GetDeferral();
   int value1 = (int)message["Value1"];    // ... 做一些处理    //向调用者返回结果
   var returnMessage = new ValueSet();
   returnMessage.Add("Result", result);
   var responseStatus = await args.Request.SendResponseAsync(returnMessage);
   messageDeferral.Complete();
   break;
   }
   case "Quit": {    // 服务端被要求退出,则调用deferral 对象的 Complete 方法,系统终止 Service
   _serviceDeferral.Complete();
   break;
   }
   }
}

4) 在清单文件中声明  App Service:

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10">
<Applications>
<Application Id="App“>
<Extensions>
<uap:Extension
         Category="windows.appService“
EntryPoint="AppServicesDemoTask.AppServiceTask">
<uap:AppService Name="microsoftDX-appservicesdemo" /></uap:Extension>
</Extensions>
</Application>
</Applications> <Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>

5)双向通信 :Client 和 server 都可以发送和接收消息

   Client 和 server 可以保持双向通信的 channel 打开着。Client 端可以给自己

AppServiceConnection 实例注册一个 RequestReceived 事件

AppServiceConnectionStatus connectionStatus = await connection.OpenAsync();
if (connectionStatus == AppServiceConnectionStatus.Success)
{
connection.RequestReceived += OnRequestReceived;
}

6)在调试的时候可以通过 Package.Current.Id.FamilyName 属性获得包的 PFN:

7)App Service 生命周期:

    · Server 端的后台任务通过设置 AppServiceTrigger 条件启动

    · Client 端可以通过调用 AppServiceConnection 对象的 dispose方法,或者发送指示命令来关闭 Service 端

    · 如果 Client 端被挂起,则相应的 Service app 会被关闭

    · 当系统资源紧张会导致 Launch 失败或者 Service 被关闭:服务端获得 AppServiceConnectionStatus.ResourcesNotAvailable消息;

      当发送消息时获得 AppServiceResponseStatus.ResourceLimitsExceeded     

11、消息中心 Action  Center Management APIs:

1)管理 app 的通知,开发者可以:

    · 移出一个或多个通知

    · 给 notification 通知添加标签和分组

    · 替换为一个新的 notification

    · 设置一个 notification 的过期时间

    · 发送一个 “Ghost Toast” notification(只显示在通知中心,但不弹给用户)

2)每个 app 最多在通知中心有 20条通知。最长保存7天(或者更短)

用户可以:

    · 追踪(单击)一个通知(从通知中心移出)

    · 移出一组通知

    · 移出所有通知

3)后台任务触发器(ToastNotificationHistoryChangedTrigger)

    当用户从消息中心解除一个 notification 或者一个 app 添加、移出、替换

  一个notification 时触发。

    

    使用这个触发器任务,app 可以保持 Toast 、Tile 消息通知的一致性。比如,

  用户移出了消息中心的 通知时,tile 上的相关消息也须移出:

// 使用 ToastNotificationHistoryChangedTrigger 触发器的后台任务
public sealed class ActionCenterChangedTask: IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var toasts = ToastNotificationManager.History.GetHistory();
if (toasts != null)
{
var count = toasts.Count();
if (count== )
{
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Clear();
}
else
{
XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
XmlElement badgeElement = (XmlElement)badgeXml.SelectSingleNode("/badge");
badgeElement.SetAttribute("value", count.ToString());
BadgeNotification badge = new BadgeNotification(badgeXml);
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);
}
}
}
}

12、Web 平台(Sparta 浏览器)

   有关 Web 更新有很多,具体视频上讲的很详细。这里只列出一点。

  从 Windows 8 开始,已经可以使用 html5/js 的方式开发 native app 了,并且不是通过 WebView 控件,

而是直接通过 JS 调用 Windows Runtime 的 api,但是不允许从 appx 包外的 JS 调用。到了  Windows 10

的 UAP,则去掉了这个限制,甚至可以通过在 app 的清单文件中,指定服务器端的地址,直接下载到本地执行逻辑,

调用 runtime 的 api。通过这种方式,很容易实现各种功能扩展。

清单文件添加服务器端的地址:

<uap:ApplicationContentUriRules>
  <uap:Rule Type="include" WindowsRuntimeAccess="all" Match="https://rjs.azurewebsites.net/" />
  <uap:Rule Type="include" WindowsRuntimeAccess="allowForWebOnly" Match="https://*.facebook.com/" />
  <uap:Rule Type="include" WindowsRuntimeAccess="none" Match="http://bing.com/" />
  <uap:Rule Type="include" Match="https://*.microsoft.com/" />
</uap:ApplicationContentUriRules>

W3C 标准  Manifest for Web Apps:http://w3c.github.io/manifest/

06、Windows 10 技术预览的更多相关文章

  1. Windows 10 技术预览版9926 “未知源”引起系统休眠后自启的解决办法

    问题的由来: 自从安装上了最新发布的Windows 10 ,使用起来有诸多的改进:无论是重绘的图标还是通知消息中心的整合还是更智能的OneDrive客户端都使得工作起来非常愉悦. 不过笔者这两天频繁遇 ...

  2. Windows 10 技术预览

    windows10的技术预览版已经发布了很久了,正式版大约在今年的夏天就会发布,作为微软寄予厚望的下一代全平台操作系统,相比于windows8.1,windows10做了哪些改进,又添加了哪些新功能. ...

  3. 熊猫猪新系统测试之一:Windows 10 技术预览版

    话说本猫不用windows很多年了呀!不过看到微软最新的Windows10还是手痒了,想安装体验一把.于是第一时间下载,并做成usb引导安装镜像,在08年的老台式机上安装尝鲜鸟.下载ISO和安装方法这 ...

  4. 熊猫猪新系统測试之中的一个:Windows 10 技术预览版

    话说本猫不用windows非常多年了呀! 只是看到微软最新的Windows10还是手痒了.想安装体验一把. 于是第一时间下载,并做成usb引导安装镜像,在08年的老台式机上安装尝鲜鸟.下载ISO和安装 ...

  5. [转帖]Windows 10新预览版上线:可直接运行任意安卓APP了

    Windows 10新预览版上线:可直接运行任意安卓APP了 http://www.pcbeta.com/viewnews-80316-1.html 今晨(3月13日),微软面向Fast Ring(快 ...

  6. 【官方免费】Apple Silicon M1 + Parallels 16技术预览版 + Win 10 arm64

    期待了好久,终于能用pd运行win10了,其实也就想写个c++,mac上配置个c++编译器太麻烦了.. 步骤: 打开 https://my.parallels.com/desktop/beta,这里下 ...

  7. 微软发布 Windows Server 2016 预览版第三版,开发者要重点关注Nano Server

    微软已经发布 Windows Server 2016 和 System Center 2016 第三个技术预览版,已经提供下载.Windows Server 2016 技术预览版第三版也是首个包括了容 ...

  8. PHP专业开发IDE——Zend Studio 10.5预览版发布

    Zend Studio是新一代的PHP IDE,高效的开发和维护PHP代码是它的核心.Zend公司目前已发布了Zend Studio 10.5预览版,预览版中提高了快速响应能力和时时误差检查.因此使用 ...

  9. Windows Server 2019 预览版介绍

    在Windows server 2012.Windows server 2016还未完全普及的情况下,昨天Windows Server团队宣布Windows Server 2019将在2018年的下半 ...

随机推荐

  1. LaTeX如何设置段落层次结构

    Latex的文档层次结构大约有5层,分别是: section — subsection — subsubsection — paragraph — subparagraph 具体使用可以参考下面的例子 ...

  2. 将matlab的figure保存为pdf,避免图片太大缺失

    有时画的matlab图太大,或者有太多的子图,导致图太宽,如果直接保存成pdf的话,会导致左右边丢失,显示不下.一个有效又简单的办法是:   1.在matlab figure里面,Edit -> ...

  3. django的动态url,url里含有参数,含有参数的url

    #!/usr/bin/env python # coding:utf- from django.conf.urls import url,include from django.contrib imp ...

  4. Could not connect to Redis at 192.168.0.129:6379: Connection refused

    在虚拟机上(CentOS 6.7)本机连接自己的redis [root@localhost bin]# ./redis-cli -h Could not connect to Redis at : C ...

  5. 实现SQL Server中的切割字符串SplitString函数

    有时我们要用到批量操作时都会对字符串进行拆分,可是SQL Server中却没有自带Split函数,所以要自己来实现了.没什么好说的,需要的朋友直接拿去用吧 SET ANSI_NULLS ON GO S ...

  6. ShellCode的编写入门

    上次学习了下堆喷漏洞的原理,虽说之前有学习过缓冲区溢出的原理,但还没了解过堆喷这个概念,于是趁此机会学习了,顺便复习了缓冲区溢出这块知识,之前由于各种原因对Shellcode的编写只是了解个大概,并没 ...

  7. 第三章 线程安全的DateFormat工具类

    1.使用threadLocal包装DateFormat(太复杂,不推荐) 2.使用org.apache.commons.lang3.time.DateFormatUtils下的方法(推荐) DateF ...

  8. android4.0 USB Camera实例(三)UVC

    前面我写了两篇文章说明了zc301的实现 详细请看 http://blog.csdn.net/hclydao/article/details/21235919 以下顺便把通用的USB也写上 前面的ZC ...

  9. 【SSH三大框架】Hibernate基础第十一篇:对继承映射的操作

    在java中.类之间能够有继承关系.可是在数据库中是没有继承关系的.只是Hibernate是为了把面向对象的关系反映到数据库中.Hibernate为我们提供了3种方案: 第一.一个继承体系放在一张表中 ...

  10. 无需编码开发快速设计互动式UI - uilang

    uilang是一个非常小巧的ui类库,可以帮助不熟悉前端代码的web设计人员快速的开发互动式UI.你只需要使用“语义式”的说明来控制元素的动态效果. 开发中你只需要在<code>标签内部输 ...