注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

MSDN Blog:打造快速而流畅的应用程序启动体验  

2012-07-26 15:00:44|  分类: Windows 8 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

应用程序启动是快速而流畅的 Windows 8 用户体验中最重要的组成部分,因此确定您应用程序启动 UX 的优先级将十分重要。高度完善的启动流程定将提高所有应用程序被用户首次接纳的概率。本篇博文将探讨应如何打造出设计精良、且反应敏捷的应用程序启动体验,并向您介绍为何应用程序的启动过程是为用户留下良好印象的关键时段。我将介绍四种应用程序启动设计模式,这四种模式可应用至您的应用程序,并指出您在继续构建 Metro 风格应用程序时需要牢记于心的一些关键内容。

应用程序启动综述

如果您已经阅读过管理应用程序生命周期,让应用程序始终充满“生命活力”的博文,那么您应该较为熟悉应用程序生命周期的状态。本篇博文重点探讨的是应用程序启动或着说是“未运行”与“正在运行”状态间的切换。

MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~
  生命周期:应用程序启动是从“未运行”状态切换至“正在运行”状态的过程。

由于应用程序启动的过程对用户高度可见,因此良好地规划这一切换过程将至关重要。这一切换过程不仅呈现于前端和中心位置,而且用户还将反复体验这一过程。您所实施的合约(参阅此前博文:在您的应用程序中激活 Windows 8 合约)越多,那么用户需要启动您应用程序的理由则越多。您给用户留下的第一印象是好是坏将取决于您对这一切换的设计方式;而且这最终也有可能决定用户是否将成为您应用程序的“回头客”。

在我向您推荐几种处理应用程序启动的方式之前,我们一同来回顾一下这一切换过程中的操作顺序,因为您将从中获益匪浅。

MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~

   应用程序启动过程中的操作顺序。

当用户启动某一应用程序时,初始屏幕将立即呈现以欢迎用户使用。每个 Metro 风格应用程序都有一个初始屏幕,该屏幕由 620x300 的图像和单色背景颜色组成。(请参阅快速入门:添加初始屏幕一文了解自定义初始屏幕的方式。)Windows 将以您的名义呈现出初始屏幕,以在激活应用程序时欢迎用户。所有应用程序在启动时都将接收已激活事件,而且该事件将让您的应用程序执行呈现其初始 UI 所需的任何初始化操作。这可能包括读取基本设置,确定应导航至的页面,和/或识别出应用程序是否已面向众多合约中的一项而激活。当初始化完成,而且您的应用程序准备好消除初始屏幕后,应用程序必须呈现其首个窗口。使用 JavaScript 编写的应用程序则无需进行这一操作,因为这已经在激活回调返回时自动完成。而使用 C# 编写的应用程序则必须通过对 Window.Current.Activate 的调用而显式进行这一操作。请勿延迟这一操作,因为如果窗口未在合理的时间内(约 15 秒)显示,那么您的应用程序将被终止。此外,您应该尽可能迅速地呈现窗口,因为不必要的长时间显示初始屏幕将迅速破坏用户体验。我们建议您在 2 至 3 秒内呈现出一个窗口,以确保用户将以其预期的情形启动您的应用程序,即便是在低端的硬件上,依然如此。

当屏幕呈现出应用程序的窗口,并消除初始屏幕后,应用程序将开始控制用户体验;此时您将决定如何引导用户使用您的应用程序的内容。由于应用程序不同,对应用程序进行适当切换的方式也将不尽相同。在接下来几个部分中,我将向您推荐四种应用程序启动模式,您可基于应用程序的需求将其应用至您的应用程序:

  • 默认的应用程序启动

适用于不需要额外加载和可立即使用的应用程序。

例如:可让用户查询或翻译多个术语的字典应用程序。登陆页面仅包含供用户输入的文本框。

  • 框架的应用程序启动

适用于需在启动时增量填充登陆页面的应用程序。

例如:可跟踪用户书籍、杂志和报纸的阅读应用程序。该应用程序在启动时将增量填充用户的库。

  • 扩展的应用程序启动

适用于需在呈现 UI 前执行长时间加载操作的应用程序。这可能包含网络调用或大量文件 I/O。

例如:显示最新比分和赛事亮点的体育应用程序。该应用程序将使用 REST API 来从网络中检索信息,并在登陆页面中显示实时数据。

  • 延迟的应用程序启动

适用于需在启动时完成基本异步任务(如查询应用程序设置以进行首次运行检查)的应用程序。

例如:需要确定用户是否已经创建帐户的游戏。系统需要该信息来确定向用户呈现哪一页面。

默认的应用程序启动

对于许多应用程序而言,“默认的应用程序启动”将是最优流程。在这一流程中,Windows 将处理各个应用程序初始屏幕的显示与消除。在系统完成激活,并显示出窗口之前,初始屏幕将一直显示,并向应用程序的登陆页面触发具有动画效果的交叉淡入淡出。如果您的登陆页面是静态的,而且不需要进行额外的加载操作,那么请使用默认启动。如果您的内容已立即就绪,那么您没有必要人为地延迟用户使用应用程序。事实上,您也不应该这么做!

以下示例显示了从 Consumer Preview 中使用 Internet Explorer 10 进行默认启动的情形。当启动应用程序时,用户将立即见到初始屏幕。初始屏幕将在应用程序激活之前一直显示,此后,初始屏幕将淡出,并转而显示登陆页面。在这一情形中,登陆页面将显示用户所访问的最后页面,由于该页面在上一次会话过程中已得以保留,因此其随时可用。

以下所列的是显示于下图中的流程:

  1. 点击应用磁贴。
  2. 显示初始屏幕。
  3. 显示应用程序登陆页面。
MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~

默认的应用程序启动流程。

您不需要进行额外的操作即可实施默认的启动流程。只需在应用程序的清单中指定 620x300 初始屏幕图像,然后再使用静态内容设计登陆页面。激活完成后,初始屏幕将淡出,转而显示您的登陆页面,随后您的应用程序将准备就绪。

框架的应用程序启动

对于大多数应用程序而言,默认启动将十分有效。在初始屏幕消除后,应用程序将开始运行,并准备与用户进行交互。然后有些应用程序在此时并未完全就绪;这些应用程序需要在启动后动态地加载内容。对于这类应用程序,“框架应用程序启动”模式将是一个不错的方式,其将尽可能迅速地让用户使用应用程序,并在此时向用户提供意义丰富的加载信息。在这一模式中,初始屏幕将消除,并转变成一个“框架”登录页(用户看到的登录页将不包含任何内容),而应用程序将在此时检索内容。通过向页面添加一个进度栏,您可向用户显示应用程序仍在加载。下一幅图像显示了从 Consumer Preview 中使用音乐应用程序进行框架启动的情形示例。此处将显示框架登陆页面,而此时应用程序正在检索最新音乐内容。

以下所列的是显示于下图中的流程:

  1. 点击应用磁贴。
  2. 显示初始屏幕。
  3. 显示框架登陆页面。请注意显示于视图顶部的进度栏。
  4. 显示应用程序登陆页面。
MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~

   框架的应用程序启动流程。

为了实施框架启动流程,您需要为应用程序的登陆页面创建一个静态的框架视图,并在您的开始页面中显示该视图。随后,在激活过程中开始执行将内容填充至页面中所需的加载任务。由于大部分操作属于异步操作,因此初始屏幕可能在系统仍在执行这些任务的时候停止。因此,您的用户将看到增量填充的登陆页面。

如果您有兴趣了解初始屏幕将在何时消除,您可使用初始屏幕 API。API 中包含 SplashScreen.Dismissed 事件,该事件可显示出何时将发生从初始屏幕到应用程序开始页面的切换。如果您希望了解用户将在何时看到您的框架登陆页面,那么这可能将对您大有裨益。

JavaScript

正如您将在以下示例中所看到的,应用程序可开始执行操作来填充激活的回调内的登陆页面。如果您希望了解初始屏幕将在何时消除,那么您可使用激活的事件参数来获取初始屏幕对象。您可使用这一对象来注册需要在初始屏幕消除后通知的已消除事件。

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// Begin executing setup operations.
performSetupTasks();

// Retrieve splash screen object.
var splash = eventArgs.detail.splashScreen;

// Register an event handler to be executed when the splash screen has been dismissed.
splash.addEventListener("dismissed", onSplashScreenDismissed, false);
...
}
};

function performSetupTasks() {
// Begin additional loading tasks here…
...
}

function onSplashScreenDismissed() {
// The splash screen has dismissed and the skeleton landing page is now in view.
...
}

C#

C# 中的实施情况与 JavaScript 完全一致。首先开始激活过程中填充登陆页面所必须的操作。然后,有选择性地从已激活的事件参数中获取初始屏幕对象,并注册需要通知初始屏幕消除信息的事件。

async protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Begin executing setup operations.
PerformSetupTasks();

// Retrieve splash screen object.
SplashScreen splashScreen = args.SplashScreen;

// Register an event handler to be executed when the splash screen has been dismissed.
splashScreen.Dismissed += new TypedEventHandler<SplashScreen, object>(eSplash.onSplashScreenDismissed);
...
}

internal void PerformSetupTasks()
{
// Begin additional loading tasks here…
...
}

internal void onSplashScreenDismissed(Windows.ApplicationModel.Activation.SplashScreen sender, object e)
{
// The splash screen has dismissed and the skeleton landing page is now in view.
...
}

扩展的应用程序启动

对于在启动后需要执行额外加载操作的应用程序而言,框架应用程序启动将是一个不错的选项。但是,这一选项也有一个弊端:由于系统将立即将用户带入“框架”页面,因此集体加载流程可能会让用户产生不连贯的感觉。从初始屏幕到框架登陆页面的切换可能会给用户留下印象,认为其中存在两个独立的加载操作。如果您不希望使用这一模式,那么“扩展的应用程序启动”模式将是一个不错的替代选项。

该流程使用“扩展的”初始屏幕的概念来打造一个无缝的加载体验。当常规初始屏幕消除后,应用程序将显示一个扩展的初始屏幕而不是登陆页面。扩展的初始屏幕将完全由应用程序所拥有,而且使用初始屏幕 API 进行了格式化。API 将提供定位信息,确保扩展的初始屏幕的外观从视觉效果上与初始屏幕完全一致(进度环和加载详情除外),这将统一看似独立的加载操作。扩展的初始屏幕处于运行状态时,应用程序可继续执行绘制登陆页面所需的操作。然后,待加载完成后,您可从扩展的初始屏幕切换至登陆页面。

如果初始化的时间较长(例如网络连接性不可预测),那么扩展的启动流程将十分有效。如果您需要在启动过程中进行任何“难度较大的操作”,那么扩展的初始屏幕将是理想的选择。此外,如果您希望确保在切换至登陆页面之前,登陆页面已充分更新(如果您选择不显示缓存的数据),那么这也将是一个不错的选择。

下一示例显示了从 Windows 8 Consumer Preview 中使用天气应用程序进行扩展的启动流程的情形。天气应用程序是可实施扩展的启动模式的众多应用程序中的经典示例,这是因为应用程序可在应用程序从网络中请求最新天气数据时向用户显示扩展的初始屏幕(向用户显示缓存的天气数据意义不大)。

以下所列的是显示于下图中的流程:

  1. 点击应用磁贴。
  2. 显示初始屏幕。
  3. 显示扩展的初始屏幕(包含进度环)。
  4. 显示应用程序登陆页面。
MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~

扩展的应用程序启动流程。

为了实施扩展的应用程序流程,您必须使用初始屏幕 API。利用 SplashScreen.ImageLocation,应用程序可获得初始屏幕图像的图像坐标。这一点相当重要,因为在扩展的初始屏幕中,图像必须定位于完全相同的位置,从而让用户获得流畅的切换过程。正如在以上部分中所提到的,API 同时将暴露 SplashScreen.Dismissed 事件,该事件将通知您从常规初始屏幕到扩展的初始屏幕的切换。

像以前一样,您可在激活过程中触发其他任务。接下来,我将向您介绍(包含可选进度环的)扩展初始屏幕在使用 JavaScript 和 C# 编写的应用程序中的实施情况。

:在实施扩展的初始屏幕时,贴靠、取消贴靠、旋转等处理同样十分重要。为保持本文内容简炼,此处省略了这些详细内容。详情请参阅初始屏幕的示例

JavaScript

首先,为您的页面添加面向(包含进度环的)扩展初始屏幕的 HTML 标记。

<div id="extendedSplashScreen" class="extendedSplashScreen hidden">
<img id="extendedSplashImage" src="/images/splash.png" style="position: absolute;" />
<progress id="extendedSplashProgress" style="color: white;" class="win-medium win-ring"></progress>
</div>
 

接下来,为扩展的初始屏幕添加 CSS 样式。

.extendedSplashScreen {
position: absolute;
text-align: center;
background-color: #000000;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.extendedSplashScreen.hidden {
display: none;
}

然后,在激活过程中开始其他操作,并使用已激活的事件参数来获取初始屏幕对象。此时,初始屏幕对象将用于注册已消除的事件和设置扩展的初始屏幕。查询初始屏幕对象,以定位初始屏幕图像,并相应排列布局。

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
// Begin executing setup operations.
performSetupTasks();

// Retrieve splash screen object.
var splash = eventArgs.detail.splashScreen;

// Register an event handler to be executed when the regular splash screen has been dismissed.
splash.addEventListener("dismissed", onSplashScreenDismissed, false);

// Display the extended splash screen.
displayExtendedSplash(splash);

WinJS.UI.processAll();
}
};

function displayExtendedSplash(splash) {
// Position the extended splash screen image in the same location as the system splash screen image.
var extendedSplashImage = document.getElementById("extendedSplashImage");
extendedSplashImage.style.top = splash.imageLocation.y + "px";
extendedSplashImage.style.left = splash.imageLocation.x + "px";
extendedSplashImage.style.height = splash.imageLocation.height + "px";
extendedSplashImage.style.width = splash.imageLocation.width + "px";

// Position the extended splash screen's progress ring.
var extendedSplashProgress = document.getElementById("extendedSplashProgress");
extendedSplashProgress.style.marginTop = splash.imageLocation.y + splash.imageLocation.height + 32 + "px";

// After the extended splash screen is set up,
// apply the CSS style that will make the extended splash screen visible.
var extendedSplashScreen = document.getElementById("extendedSplashScreen");
WinJS.Utilities.removeClass(extendedSplashScreen, "hidden");
}

在扩展的初始屏幕显示时指定需要完成的加载任务。当加载完成时,停止扩展的初始屏幕。确保正常处理错误情况;如果加载任务超时或失败,将用户切换至可解释所发生情形的页面。

function performSetupTasks() {
// Begin additional loading tasks here…
...

// Tear down the extended splash screen after all operations are complete.
removeExtendedSplash();
}

function onSplashScreenDismissed() {
// The splash screen has been dismissed and the extended splash screen is now in view.
...
}

function removeExtendedSplash() {
var extendedSplashScreen = document.getElementById("extendedSplashScreen");
WinJS.Utilities.addClass(extendedSplashScreen, "hidden");
}

C#

与 JavaScript 中的情形类似,我们需要为包含进度环的扩展初始屏幕添加标记。这次我们将使用 XAML。

<!-- This snippet represents the ExtendedSplash class -->
<Canvas Grid.Row="0">
<Image x:Name="extendedSplashImage" Source="images/splash.png" />
<ProgressRing x:Name="ProgressRing" Foreground="White"
HorizontalAlignment="Center" IsActive="True"
MaxHeight="30" MinHeight="30" MaxWidth="30"
MinWidth="30"></ProgressRing>
</Canvas>

同样,我们将在激活过程中启动加载任务。随后我们将从激活事件参数中获取初始屏幕,并显示扩展的初始屏幕。

async protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Begin executing setup operations.
PerformSetupTasks();

// Retrieve splash screen object.
SplashScreen splashScreen = args.SplashScreen;

ExtendedSplash eSplash = new ExtendedSplash(splashScreen);

// Register an event handler to be executed when the splash screen has been dismissed.
splashScreen.Dismissed += new TypedEventHandler<SplashScreen, object>(eSplash.onSplashScreenDismissed);
...

Window.Current.Content = eSplash;
Window.Current.Activate();
}

public ExtendedSplash(SplashScreen splash)
{
InitializeComponent();

// Position the extended splash screen image in the same location as the splash screen image.
this.extendedSplashImage.SetValue(Canvas.LeftProperty, splash.ImageLocation.X);
this.extendedSplashImage.SetValue(Canvas.TopProperty, splash.ImageLocation.Y);
this.extendedSplashImage.Height = splash.ImageLocation.Height;
this.extendedSplashImage.Width = splash.ImageLocation.Width;

// Position the extended splash screen's progress ring.
this.ProgressRing.SetValue(Canvas.TopProperty, splash.ImageLocation.Y + splash.ImageLocation.Height + 32);
this.ProgressRing.SetValue(Canvas.LeftProperty,
splash.ImageLocation.X +
(splash.ImageLocation.Width / 2) - 15);
}

在显示扩展的初始屏幕时执行必要的加载任务,然后导航至登陆页面。

internal void PerformSetupTasks()
{
// Begin additional loading tasks here…
...

// Tear down the extended splash screen after all operations are complete.
RemoveExtendedSplash();
}

internal void onSplashScreenDismissed(Windows.ApplicationModel.Activation.SplashScreen sender, object e)
{
// The splash screen has been dismissed and the extended splash screen is now in view.
...
}

void RemoveExtendedSplash()
{
Window.Current.Content = new LandingPage();
}

延迟的应用程序启动

我将与各位探讨的最后一种启动模式是“延迟的应用程序启动”。延迟的启动与扩展的启动类似,其可在初始屏幕切换之前启用对登陆页面的准备操作。应用程序不是显示“扩展的”初始屏幕,而是延迟常规初始屏幕的消除,直至执行异步任务。由于应用程序完成该延迟的时间有限,因此您应谨慎使用延迟模式,而且应在系统显示应用程序之前完成诸如读取应用程序设置等简单异步操作。此外,如果您无法在此时恰当地处理错误/异常,那么启动有可能被终止。相应地,如果您的应用程序需要进行网络调用或处理大量数据,则应使用框架或扩展应用程序启动模式。

以下示例显示了从 Consumer Preview 中使用照片应用程序进行延迟启动的情形。当用户从桌面打开 .jpg 文件时,照片应用程序将作为此类文件的默认处理程序而被启动。照片应用程序将使用延迟来在初始屏幕消除前加载图像缩略图。由于缩略图检索操作可相对迅速地完成,因此延迟的使用可被接受。随后,在用户进入应用程序后,系统可异步获取较高分辨率图像来更换缩略图。这一流程可确保缩略图在用户切换至应用程序之前显示于屏幕中。

以下所列的是显示于下图中的流程:

  1. 点击 .jpg 图像(照片应用程序是 .jpg 的默认处理程序)。
  2. 显示初始屏幕。
  3. 延迟激活,同时检索缩略图。
  4. 以缩略图显示应用程序。
MSDN Blog:打造快速而流畅的应用程序启动体验 - 乂乂 - 一个人,一支烟  ·~~ 

延迟的应用程序启动流程。

为了在使用 JavaScript 编写的应用程序中实施延迟的启动流程,您必须使用激活延迟。延迟将让应用程序延迟激活的完成,直至异步操作完成。否则,激活将在回调返回时完成。由于大多数 Windows 运行时 API 是异步 API,因此这对于希望确保所有操作均在应用程序的初始 UI 显示前完成的应用程序而言十分重要。在使用 C# 编写的应用程序中,应用程序可通过延迟 Window.Current.Activate 调用来实现延迟。接下来,我们将分别介绍这两种方法。

JavaScript

在使用 JavaScript 编写的应用程序中,您可根据应用程序处理激活的方式而使用两种方式来实现激活延迟。

如果您的应用程序使用 WinJS 来处理激活(VS 项目模板的默认选项),那么请使用以下代码。在激活事件参数中调用 setPromise 将延迟激活的完成,直至异步调用(WinJS.UI.processAll 和 asyncOperation)完成。

app.onactivated = function (eventArgs) {
if (eventArgs.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
eventArgs.setPromise(WinJS.UI.processAll().then(function() {
return asyncOperation().done(function () { });
}));
}
};

如果您手动注册处理已激活的事件,那么您可使用 ActivatedOperation.getDeferral 方法。在下方,系统将在激活过程中获取一个延迟的对象,而且将在所有异步操作完成后调用 complete

注:无论异步调用是否成功,系统都必须调用 complete。如果 complete 未被调用,那么应用程序将永远无法从激活返回,而且应用程序启动将超时。这是使用这一模式的一个常见缺点;确保您的应用程序可处理所有错误情形将十分重要。

Windows.UI.WebUI.WebUIApplication.addEventListener("activated", onActivated, false);
function onActivated(eventArgs) {
if (eventArgs.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
var deferral = eventArgs.activatedOperation.getDeferral();
asyncOperation().done(function () {
deferral.complete();
}, function (error) {
deferral.complete();
});
}
}

C#

如需在使用 C# 语言编写的应用程序中实施延迟,您只需延迟 Window.Current.Activate 调用,直至您的加载操作完成。请记住,与 JavaScript 中的情形类似,您仅可延迟这一调用来完成简单的操作。如果您的应用程序未在合理的时间内成功激活其窗口,那么启动将超时。此外,时间较长的延迟将对您应用程序的感知性能产生负面影响,从而对您和用户的关系不利。

protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
// Create a frame to act navigation context and navigate to the first page.
var rootFrame = new Frame();
rootFrame.Navigate(typeof(BlankPage));

// Place the frame in the current Window and ensure that it is active.
Window.Current.Content = rootFrame;

// Use “await” to execute an async operation prior to activating a window.
// Remember, avoid lengthy operations here.
await asyncOperation();

Window.Current.Activate();
}

结论

在本篇博文中,我们探讨了打造卓越启动体验的几项技术。为了让您应用程序的外观从海量应用程序中脱颖而出,我们一同了解了四种可应用至所有 Metro 风格应用程序的特定设计模式。在您继续构建应用程序过程中,请记住优先应用程序的启动,并使用本篇博文中所简要介绍的几种模式。毕竟,这是您让用户对您的应用程序留下深刻印象的首次机会。

有关激活、初始屏幕或应用程序生命周期的更多信息,请查看以下资源:

链接

类型

要点

添加初始屏幕

文档

有关初始屏幕和扩展初始屏幕的宽泛概述。其中同时包含有用的设计指南。

初始屏幕示例

示例

展示在使用 JavaScript、C#、C++ 和 VB.NETSDK 编写的应用程序中使用扩展的应用程序启动模式的示例。

SplashScreen 类

API 参考

有关初始屏幕类的 API 文档。

如何激活使用 VB/C#/C++ 和 XAML 编写的应用程序

快速入门

有关激活使用 C#、C++ 或 VB.NET 编写的 Metro 风格应用程序的教程。

如何激活使用 JavaScript 和 HTML 编写的应用程序

快速入门

有关激活使用 JavaScript 编写的 Metro 风格应用程序的教程。

应用程序激活和挂起示例

示例

展示使用 JavaScript 编写的 Metro 风格应用程序激活和挂起的 SDK 示例。

Windows.ApplicationModel.Activation 命名空间

API 参考

有关激活命名空间的 API 文档。

WebUIApplication.activated 事件

API 参考

有关已激活的事件的 API 文档。

应用程序生命周期

文章

介绍 Metro 风格应用程序生命周期的文章。

--Justin Cooperman,Windows 用户体验团队项目经理

【from  http://blogs.msdn.com/b/windowsappdev_cn/archive/2012/05/30/fast-and-fluid.aspx 】
  评论这张
 
阅读(926)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017