admin管理员组

文章数量:1560430

原文:Beginning Windows Store Application Development – HTML and JavaScript Edition

协议:CC BY-NC-SA 4.0

零、简介

几个月前,当我被问到写一本关于用 JavaScript 为 Windows 8 构建应用的书时,我的第一个想法是,“写这本书我能带来什么?”其他作者已经讨论了这个主题,但是当我回顾了一些其他的书,我意识到我可以通过这个项目来填补这个空白。

我希望看到一本书,不仅涵盖基本的技术概念,而且还能从头到尾引导初学者完成构建商业质量的真实应用的过程。我想要一本书,不仅提供代码片段,还提供改善读者应用用户体验的技巧。我想要一本书,更多的是一个指南,而不是参考,介绍对读者来说可能是新的概念,而不是更深入地挖掘你可能在另一本书中找到的熟悉的主题。我希望有一天你可以拿起一本书,几天后你就可以构建真正的应用。

开始 Windows Store 应用开发—HTML 和 JavaScript 版本是我提供一本我想读的书的尝试。在写这本书的时候我学到了很多,我希望你通过阅读它也能学到很多。

这本书是给谁的

本书面向具有使用 HTML、CSS 和 JavaScript 构建 web 应用的经验,并对使用现有技能构建 Windows 8 应用感兴趣的开发人员。对于那些有使用其他技术(如. NET)为早期版本的 Windows 构建应用的经验的人来说,它也是一个很好的初学者指南。对于那些经验较少的人来说,它涵盖了 HTML、CSS 和 JavaScript 主题,但本书的重点不是这些技术本身,而是使用这些技术来构建 Windows 应用商店应用。

在本书中,我将提醒您,就像构建 web 应用一样,您可以自由地遵循您喜欢的 HTML、CSS 和 JavaScript 实践。例如,当创建页面控件时,我选择将 Visual Studio 创建的 CSS 和 JavaScript 文件保存在 HTML 文件所在的目录中,这将在第五章第一次演示,但在整本书中大量使用。因为我的大部分背景是. NET 开发人员,所以这很熟悉,因为默认情况下,Visual Studio 将 ASPX 和 ASCX 文件保存在与文件背后的 C#或 VB 代码相同的目录中。但是,您可以选择将所有 JavaScript 文件移动到 js 文件夹,将所有 css 文件移动到 CSS 文件夹。此外,您可能会注意到,我写的 JavaScript 代码不是地道的 JavaScript。请随意修改代码示例,以符合您的编码风格。

这本书的结构

虽然你当然可以直接跳到你感兴趣的主题,但这本书是为从头到尾阅读而写的,每一章都建立在前一章的基础上。在第一章到第三章中,你会发现 Windows 8 概念的概述,比如触摸界面和手势,以及微软设计语言。在第四章到第八章中,我将向您介绍如何使用 Visual Studio,包括各种可用的项目模板,以及您可能在应用的用户界面(UI)中使用的不同控件。

在第九章和第二十二章之间,你将构建一个功能齐全的真实应用。每章将涵盖 Windows 应用商店应用开发的核心概念,用 HTML 和 JavaScript 实现。每章的主题不一定是下一章的先决条件,但是示例应用已经过精心设计,因此每一章中的代码示例都建立在前面几章的基础上。

最后,在第二十三章中,我将介绍一些你应该采取的步骤来打造你的应用并将其发布到 Windows 商店中。

下载代码

本书中所示示例的代码可在 Apress 网站www.apress上获得。在该书的信息页面上的源代码/下载选项卡下可以找到一个链接。该选项卡位于页面的相关标题部分下。

此外,在第九章到第二十三章中构建的示例应用的源代码可以在 GitHub 上的www.github/daughtkom/Clok处获得。

联系作者

如果你有任何问题或意见——甚至是你认为我应该知道的错误——你可以通过我的个人网站联系我,地址是www.scottisaacs,或者在 Twitter 上联系我,地址是www.twitter/daughtkom

一、欢迎来到触摸优先的世界

2010 年 4 月,我第一次听到定义微软新战略的短语:“三块屏幕和云。”这指的是一种有针对性的方法,以确保微软的产品在手机、台式电脑和电视屏幕上无处不在,并且这些平台通过在云端与数据结合在一起提供无缝体验。三个屏幕上展示的产品分别是 Windows Phone 7、Windows 7 和 Xbox 360。微软仍然主导着电视屏幕,其 Xbox 系列约占全球销售的所有游戏主机的一半,并继续专注于将该平台转移到游戏之外,但对我来说,Windows 8 给三个屏幕和云带来了不同的意义——其中三个屏幕包括手机、平板电脑和个人电脑,所有这些都运行在 Windows 8 核心上,并与云服务绑定,如图 1-1 所示。

图 1-1 。Windows 8 三屏和云的愿景

这本书是关于在这个新环境中开发应用的,但是在你开始任何开发之前,你必须了解这个环境以及它将如何被使用。在这一章中,我将提供一些关于 Windows 8 用户界面的背景知识,以及用户将如何与运行在该平台上的应用进行交互。我将主要关注触摸,但由于 Windows 8 是一个触摸优先的环境,而不是只有触摸的环境,我也将讨论触摸何时不合适,并涵盖替代的输入方法。

移动到更自然的交互

1985 年,用户主要通过使用键盘与 PC 进行交互,但第一台 Macintosh 正在增加鼠标的普及程度,微软推出了 Windows 1.0,它本质上是一个外壳,允许人们点击打开程序和文档,而不是要求他们记住适当的命令来打字。这些基于鼠标的环境在商业和消费市场上都取得了成功,并使大众能够进行计算:到 Windows 95 发布时,个人电脑在人们的家庭中并不罕见。

多年来,计算机和软件制造商一直在考虑可以放在口袋里或挂在腰带上随身携带的计算机。苹果早在 1992 年就试图实现这一愿景,但直到 2000 年代中期,技术才真正跟上,硬件制造商才能制造出小型、轻量级的计算设备,能够运行与台式机相当的软件。当硬件为消费者的黄金时间移动计算做好准备时,Windows 品牌在市场上已经根深蒂固,微软用 Windows CE、Pocket PC 和各种 Windows Mobile 进行了几次尝试,以创建一个简单的 Windows 缩小版的移动体验。这种方法产生的屏幕需要很高的交互精度,而运行移动版 Windows 的电脑在很大程度上被视为专用设备,不被普通消费者接受。

2010 年 Windows Phone 7 的推出,可能是受三年前苹果 iPhone 的成功和随后安卓的流行的推动,摒弃了小版本 Windows 的概念,并采用了一种被称为微软设计语言的全新用户界面概念。微软设计语言基于一套以用户为中心的核心设计原则,手指成为与计算机交互的主要工具。与之前版本的微软移动操作系统不同,Windows Phone 设备不再将手写笔作为标准组件。

你可能对地铁这个名词比较熟悉。 Metro 是微软和其他公司以前在一些不同的上下文中使用的代号。微软设计语言被广泛称为 Metro 设计语言。此外,Windows 开始屏幕通常被称为 Metro 界面。以前称为 Metro 应用的应用正式称为 Windows 应用商店应用。

随着 Windows 8 的推出,微软抓住机会按下了用户界面期望的“重置”按钮,并通过将移动世界中必然会出现的交互带到桌面环境中,而不是将桌面概念带到移动世界,扭转了之前的策略。

Windows 8 触摸语言

随着触控作为一等公民在 Windows 8 中的全面融入,了解操作系统识别的触控手势语言非常重要。这不仅对于 Windows 8 用户来说很重要,对于希望确保用户能够尽快学习应用并获得一致体验的开发人员来说更是如此。Windows touch 语言主要由八种手势组成,我将在本节中讨论。

按住

按住手势 如图图 1-2 所示,类似于鼠标右键手势。该手势旨在允许用户了解关于目标的一些信息,或者向用户提供额外的选项,如上下文菜单。这种手势是通过用单个手指触摸屏幕并暂停直到系统确认保持来实现的,通常是通过描绘保持的用户界面元素来实现的。

图 1-2 。按住

龙头

虽然按住手势可以很容易地等同于单个鼠标手势,但对于轻击手势来说就不一样了。在图 1-3 中所示的点击手势旨在调用用户界面元素上的主要动作。通常,这是一个动作,比如激活一个按钮或跟随一个链接。与点击手势最相似的鼠标手势是左击,但是左击也用于在触摸语言中具有自己的手势的其他任务,例如选择。这个手势是通过将手指放在用户界面元素上,然后立即将手指垂直抬起来实现的。

图 1-3 。龙头

幻灯片

Windows touch 语言中的滑动 手势,如图图 1-4 所示,用于平移或滚动超出屏幕或屏幕部分边界的内容。在鼠标驱动的环境中,这是通过使用滚动条来实现的,但在触摸环境中,滑动手势更自然,滚动条要么必须增长到占用屏幕太多空间的程度,要么就是一个很难触摸的目标。为了完成滑动手势,手指放在屏幕上,然后上下或左右拉动,这取决于内容的方向。

图 1-4 。幻灯片

偷窃

滑动 手势用于传达选择,很像使用鼠标和键盘与计算机交互时使用的左键单击、Ctrl+左键单击和 Shift+左键单击。为了实现这个手势,如图图 1-5 所示,手指放在屏幕上所选项目的上面或旁边,然后在项目中划过。手势的方向取决于内容的方向,水平方向的内容被垂直滑动,垂直方向的内容被水平滑动。这种与滑动相反的手势有时会被称为交叉滑动。使用这种手势,而不是点击,可以消除在没有键盘修饰键(如 Ctrl 和 Shift)来帮助鼠标选择的情况下尝试完成多选时可能出现的混乱。

图 1-5 。偷窃

少量

在图 1-6 中所示的捏捏 手势在大多数鼠标中没有直接的等效物,被认为是一种“缩放”手势。夹点从具有高细节级别的窄视图缩小到具有较少细节的更宽视图。你将在后面的章节中看到,除了光学变焦,应用还可以在语义级别利用这种手势,并使用它来导航摘要和详细数据。为了完成捏手势,两个手指分开放置,并且与作为手势目标的元素的中心大致等距,然后手指一起滑动,直到达到期望的缩放或者手指相遇。

图 1-6 。少量

注意在许多带有滚轮的鼠标上,滚动时按下 Ctrl 键执行与收缩或拉伸手势相同的动作。

伸展

拉伸 手势,如图图 1-7 所示,是捏手势的反义词,在执行和结果上都是如此。拉伸手势用于从较宽、不太详细的视图放大到较窄、包含更多细节的视图。就像捏一样,你会发现应用可以被设计成允许手势是光学缩放还是语义缩放。为了完成手势,手指放在一起,以要缩放的元素为中心,然后沿着屏幕向相反的方向移动,直到达到所需的缩放级别或者其中一个手指到达屏幕的边缘。

图 1-7 。伸展

从边缘滑动

随着你对 Windows 8 和微软设计语言的了解越来越多,你会发现内容才是王道,任何分散内容注意力的东西都应该从屏幕上消失。您还会发现,用户必须能够尽可能轻松地执行操作。Windows Store 应用通过将不常访问的命令放在屏幕边缘的所谓应用栏魅力栏 来平衡这些需求。图 1-8 中的从边缘滑动手势用于访问这些命令。为了实现该手势,手指被放置在屏幕边缘之外,然后被拉到屏幕上。

图 1-8 。从边缘推送

转动

转动 手势,如图图 1-9 所示,用于旋转视图或视图内的内容。这种手势的一个例子是经典视频游戏俄罗斯方块的触摸版,其中下落的方块可以旋转到一起。为了完成这个手势,将两个手指放在屏幕上,然后将两个手指绕着一个圆的圆周拉动,或者一个手指绕着另一个手指旋转,后者保持静止。

图 1-9 。转动

成功触摸界面的关键

构建一个成功的触摸界面需要设计者和开发者的仔细思考和考虑。这些考虑因素中的许多都包含在管理微软设计语言的设计原则中,我将在第二章中讨论,但在这一节中,我将讨论一些对触摸界面至关重要的概念,无论它们是否使用这些原则。

响应性

虽然响应速度对任何应用都很重要,但对于触摸应用的用户来说,永远不要看着没有响应的屏幕是特别重要的。用户意识到,即使只是在潜意识层面,鼠标指针是比手指末端更精确的工具,因此如果不容易看出用户的最后命令被接受并被执行,用户可能会觉得他或她没有击中目标并再次发出命令。响应性可以通过一些操作来实现,例如给出一个长时间运行的过程已经开始的视觉线索,或者确保内容随着用户的手指在屏幕上拖动而移动。

触摸目标

如前一节所述,鼠标指针是一种比人类指尖精确得多的工具。虽然在某些应用中没有什么可以消除用户错过目标的可能性,但是使用间隔很大的大触摸目标是最大限度减少错过目标的重要方法。在所有可能的情况下,目标应不小于 7 毫米见方,它们之间至少有 2 毫米。一般来说,当击中错误的目标造成严重后果或难以纠正时,该目标的比例应该更大,并且它与其他目标之间也应该有更大的空间。

直观的界面

对最终用户来说,最好的应用“就是工作”通常,这是因为应用使用户更容易做需要做的事情,而不是弄清楚如何做需要做的事情。如今,许多桌面应用通过在工具提示中提供详细的说明来弥补直观性的不足,当用户用鼠标指针浏览应用时,工具提示就会出现。触摸界面仍然可以使用工具提示,触摸语言为这种类型的学习定义了按住手势,但这比使用鼠标需要更多的努力,所以应该在清晰传达用户应该做什么的设计上投入更多的努力。

关于实现高质量基于触摸的用户体验的额外指导,请参考这两篇 MSDN 文章:http://msdn.microsoft/en-us/library/windows/apps/xaml/hh465415.aspxhttp://msdn.microsoft/en-us/library/windows/desktop/cc872774.aspx

触摸不到

和 Windows 8 一样,本章非常重视用户通过触摸手势与电脑的互动。然而,应该注意的是,Windows 8 用户界面被称为触摸优先 ,而不是纯触摸。Windows 8 拥有在 Windows XP 和 Windows 7 上运行的大部分硬件上运行的能力,并且在许多情况下,由于为适应移动设备而进行的优化,性能会更好。这意味着,尽管供应商们正争先恐后地向市场推出创新的触摸硬件,但在可预见的未来,应用开发人员必须承认,他们的许多用户将只使用键盘和鼠标来开发应用。

除了仍在使用的大量旧硬件之外,了解一些使用场景并不能很好地转化为触摸环境也很重要。用户坐着数小时进行数据输入,将会比用户使用键盘和鼠标进行同样的任务,伸出手臂去够像今天大多数显示器一样设置的触摸屏显示器更舒服,并且更少疲劳和损伤。硬件供应商将通过继续创新来满足这一新需求,您可能会看到一些变化,如多点触控板取代传统的鼠标和显示器,这些鼠标和显示器可以调整为平放或至少倾斜在桌面上。此外,预计会看到类似于微软 Kinect 设备的设备不断发展,并以比今天更具创新性的方式使用。

结论

在本章中,您将 Windows 8 视为您的应用将生活在其中的触摸优先世界。您了解了 Windows touch 语言中定义的基本手势,以及最终用户期望应用如何对这些手势做出反应。您还了解到,无论未来的计算机是什么样子,今天的计算机通常看起来非常像 Windows 8 上市前一天甚至五年前销售的计算机,您的应用必须考虑到今天计算机的用户。不管用户是用手还是鼠标进行交互,Windows 应用商店应用都应该流畅、直观、响应迅速。

二、微软设计语言

除了上一章讨论的基本触摸原则,微软的设计团队开发了微软设计语言,以前称为 Metro,用于指导 Windows Phone 7、Windows Phone 7.5 以及现在的 Windows 8 和 Windows Phone 8 的用户界面开发。微软设计语言的灵感来自于在大都市地区和公共交通中看到的简单易懂的语言,并努力将这种简单和直观的味道带到计算中。在这一章中,我将介绍微软设计语言的元素,展示一些例子,并解释 Windows 8 是如何整合它们的。在进入微软设计语言本身之前,我将介绍一下瑞士设计风格,它的影响在微软设计语言的元素中可以清楚地看到。

瑞士设计风格

微软的设计语言受一种设计风格的影响最大,这种风格被称为瑞士设计风格,或国际印刷风格,它于 20 世纪 50 年代在瑞士发展起来,并在 20 世纪 60 年代和 70 年代真正开始形成自己的风格。

包豪斯的影响

瑞士的设计风格深受包豪斯运动的影响,瓦尔特·格罗皮乌斯于 1919 年在德国魏玛成立了包豪斯艺术学院。包豪斯运动的指导原则是功能胜于形式,因此支持简洁的交流和鲜明的对比胜于抽象的想法和渐变。它促进了为工业化社会设计的艺术和建筑,并且可以大规模生产。包豪斯运动对现代设计和建筑的发展产生了重大影响。如今,网站http://Bauhaus-online.de由柏林包豪斯设计档案馆/博物馆、魏玛经典基金会和包豪斯德绍基金会(见图 2-1 )维护,旨在保存和传播关于学校的信息,并教育人们了解该机构的影响。

图 2-1 。德国德绍的包豪斯建筑

瑞士设计风格的元素

瑞士设计风格的特点是有许多元素,我将在本章中讨论。这些元素包括排版,摄影,图像,大量使用空白,以及严格的组织。这些元素结合在一起,产生了瑞士风格设计作品的独特外观和感觉。

排印

受瑞士设计风格原则影响的艺术的前沿和中心是字体设计。瑞士风格的开发者,以及今天使用这种风格进行设计的人,坚定地认为文本应该清晰简单,不必要的装饰不仅遮蔽了文本中所传达的信息,还会分散人们的注意力。为了与文本应该清晰、简洁和简单的理念保持一致,瑞士设计通常采用无衬线字体,文本左对齐,右参差不齐。图 2-2 和 2-3 是新闻稿的示例,设计为两端对齐的列和衬线字体(Times New Roman),后面是使用无衬线字体(Helvetica)和左对齐设计的相同新闻稿,以符合瑞士设计风格原则。请注意两个例子之间的显著差异,特别是字体,以及无衬线字体如何产生更整洁的外观。标题是这方面特别好的例子。

图 2-2 。非瑞士风格的模拟时事通讯

图 2-3 。使用瑞士风格排版的模拟时事通讯

除了关注简单的无衬线字体之外,瑞士设计在排版方面的另一个关键元素是使用对比字体大小和粗细来吸引对文本中某些点的注意或强调。当使用不同的字体大小时,这需要字体大小的明显差异,因此尽管一些设计学校可能提倡 12 点的标题和 10 点的正文,但瑞士设计可能要求 18 点的标题和 10 点的正文,以确保这两种文本元素之间的差异没有问题。

摄影

瑞士设计风格的另一个特点是,设计应该传达一种真实感,当用照片代替图画时,视觉元素会被认为“更真实”。

图 2-4 展示了一片水域上的日落。照片捕捉到了水中的波纹和阳光对水面的影响,给观众一种非常真实的感觉。

图 2-4 。水面上日落的照片

图 2-5 也描绘了一片水域上的日落。照片中出现了许多相同的元素,如水中波纹的阳光反射和轮廓,但推动瑞士设计的理论认为,当使用插图而不是摄影时,观众不会感到他们所看到的是真实的。照片和画都很赏心悦目,但照片更符合瑞士风格。

图 2-5 。水面上日落的画

肖像学

虽然照片比图画或其他插图更受欢迎,但在许多情况下,使用瑞士设计创作的作品通常会大量使用图标,以增加或取代文本。尤其是当瑞士设计用于必须向国际观众传达信息的场合,或者您不能确定需要传达信息的观众是否能理解印刷的文字,不管它们是用什么语言写的。1972 年德国慕尼黑夏季奥运会期间,丰富的图标与瑞士设计的其他元素结合在一起,在国际舞台上大放异彩。奥托·艾舍为奥运会设计了瑞士风格的小册子和传单,并使用了现在人们熟悉的图形图标系统来代表参加奥运会各种活动的个人。这促进了与出席奥运会的国际观众的交流。你还可以在公共汽车站和火车站、公共洗手间(图 2-6 )以及许多消费品上的警告标签中看到瑞士设计和图标的突出例子。

图 2-6 。熟悉的瑞士风格设计有助于避免尴尬的错误

大量使用空格

在瑞士设计中,内容为王。在一个空间里随意放入太多东西会被认为过于杂乱或嘈杂,会分散对所传达信息的注意力。这导致了一个包含大量空白的设计目标,以确保出现在空白区域的任何东西都会立即成为关注的焦点。

图 2-7 显示了一只狗在一个多雪的国家里站岗。“哨兵”是一个描述性的说明,但没有特别注意狗或说明,因为内容都允许一起运行,没有任何分离,因为树木产生的“噪音”分散了说明的信息。虽然这个数字在视觉上很吸引人,但它缺乏瑞士设计原则所青睐的鲜明对比。我将利用大片雪地中的自然空白来突出照片中我希望引起注意的部分和标题,如图图 2-8 所示。

图 2-7 。没有空白的照片和说明

图 2-8 。照片和说明带有空白以形成对比

在图 2-8 中,我所做的唯一改变是将文本从树木产生的噪音中移除,让标题独立存在于不间断的空白中。这缩小了照片的焦点,排除了与主题没有直接关系的部分,真正使标题突出。更多的照片可以从顶部和底部裁剪,以使主体更加集中,但在这种情况下,足够的空间来确保冬季场景不会逃过观众的眼睛。无论是第一个版本还是第二个版本都不应被视为更好或更差,因为在有些情况下,目的是关注整个环境,而坚持瑞士设计的原则不是目标,在这种情况下,第一种处理方式可能是首选。

严密的组织

为了与简洁和避免任何干扰内容的主题保持一致,瑞士设计通常以严格的组织为标志。这体现在几何图形的一致性,以及在文本中使用字体大小来传达信息层次,以及坚持使用网格系统以结构化的方式布局文本和其他视觉元素。网格的使用绝对不局限于瑞士风格,它已经在排版设计中使用了几个世纪。在基于网格的设计中,设计图面被划分为一个或多个网格,这些网格用于定位带有单元格的文本和元素。这提供了一个有组织和一致的外观。有时,网格布局的使用可能不太明显,因为网格线不需要与设计图面的边缘垂直和平行,这使得设计可以遵循网格布局,而内容在查看者看来是倾斜的。

图 2-9 显示了通过使用网格布局实现的结构组织,但它也展示了在瑞士设计风格中,通过使用字体大小的明显差异来描绘信息层次中的不同级别,排版被用来实现组织的方式。在信息层次的最高层,页眉以 56 磅的字体大小显示。在下一个级别,组标题的字体大小大约是页面标题的一半。在此页面的最底层,项目标题大约是组标题大小的一半。

图 2-9 。演示网格布局和层次结构的 Windows 应用商店应用

微软设计语言

微软设计语言在很大程度上植根于我刚才提到的瑞士设计风格,它指导着 Windows Phone 7/7.5/8 和 Windows 8 操作系统以及 Zune 和 Xbox 360 用户界面的用户体验设计,努力提供一致的外观和感觉,而不管您正在与什么设备进行交互。

微软设计语言原则

微软最早关于微软设计语言的指南将其描述为五个指导原则的汇合,而不是一本规则或食谱。在这一节中,我将介绍您在做出设计选择时应该权衡的原则。

展现对工艺的自豪感

在你的用户界面中,即使是最小的细节也不应该碰运气。用户看到的和经历的一切都应该是计划的一部分,并按照计划工作。此外,信息应该按照精心设计的视觉层次来呈现,并且应该使用基于网格的设计来布局。

快速流畅

应用应该允许用户直接与内容交互,并且应该通过使用 motion 为交互提供反馈来保持持续的响应。应用通常应该以“触摸优先”为设计理念。

真正的数字

微软失败的用户体验实验的一个最明显的例子是 1995 年微软 Bob 的发布。该应用是操作系统的外壳,旨在通过为不同的操作提供真实世界的类比来抽象出计算机的整体“计算机性”。如果您想要检索文档,请单击文件柜。需要写信吗?点击桌上的笔!鲍勃的失败最终是由两个因素造成的。第一个是它被认为是幼稚和傲慢的(许多类似于 Bob 的贝壳确实在幼儿园教室里很受欢迎)。第二,它根本不是人们与计算机交互的有效方式,引入旨在隐藏计算机的抽象概念往往会使交互效率大大降低,尤其是对于一天中大部分时间都必须使用计算机的人来说。微软设计语言原则承认人们知道他们正在与计算机交互,并呼吁设计师拥抱这种媒介。这包括使用云来保持用户和应用的连接,并有效地使用运动和大胆,充满活力的颜色与用户交流。

少花钱多办事

Windows 8 提供了丰富的功能,允许在您的设备和云中运行的应用相互交互。这使得应用能够专注于做一组定义非常狭窄的事情,并以非凡的方式做一件事情,而不是做不好几件事情。为了与包豪斯和瑞士设计的影响保持一致,内容应该是注意力的主要焦点,并且应该很少出现其他东西来分散对内容的注意力。Windows 应用商店应用的全屏特性甚至消除了对窗口 chrome 的需求,允许完全沉浸式的体验,因此当用户在您的应用中时,您的应用会受到他或她的所有关注。

团结一致赢得胜利

在 Windows Store 应用中工作的一个关键是样式已经设置好了。Windows Store 应用的用户在打开您的应用时,会期望他们已经对它有了一定程度的熟悉,因为他们熟悉其他 Windows Store 应用的外观和感觉。一些对单个应用,最终对应用所在的生态系统真正有害的事情是设计决策,这些决策从根本上改变了应用的设计范式,为用户提供了比他们习惯拥有的更“新”和“更好”的东西。你应该努力让你的用户知道你的应用做了它应该做的事情,但是试图通过改变用户界面和导航范例来给用户惊喜只会让他们迷惑,让他们对你的应用失去信任。Microsoft 提供了指南、工具、模板和样式表,使开发人员可以轻松创建外观一致的 Windows 应用商店应用,您应该充分利用这些资源。

Windows 应用商店应用的用户体验指南

除了微软为 Windows Store 应用发布的更为通用的原则之外,还发布了一套全面的指导原则,以便为在这一新生态系统中运行的应用的外观、感觉和行为提供详细的规范性指导。虽然这些指南的全部内容可以在 MSDN 图书馆网站http://dev.windows上免费获得,但本节并没有全面论述,而是涵盖了最适用于体验 Windows 8 的设计人员/开发人员的几个方面。

应用布局

应用应该使用网格布局来设计,按照内容的要求,使用层次导航方案或平面视图来组织。

当采用分级方法时,分级的顶部代表最低级别的细节,并且导航分级中的每个后续级别随着细节的增加而放大。通常,最高级别,有时被称为中心 ,是应用的入口点,显示用户可以进入的一个或多个组(参见图 2-10 )。

图 2-10 。最高层分层导航(Hub)

通过从主枢纽选择一个组,显示下一级导航(通常称为部分)。章节页面被安排来提供一些关于章节本身的上下文,并列出最低导航级别和最高细节级别的单个项目(见图 2-11 )。

图 2-11 。部分级别的分层导航

在节页面中,用户可以通过使用返回箭头(如图 2-11 所示)返回上一级导航到中心,这是一种通过滑动手势(如果启用触摸)或通过使用屏幕左右边缘垂直居中的箭头导航到同级节页面的方法,或者选择项目以继续到详细页面。在导航的详细页面级别,呈现项目数据的粒度视图(参见图 2-12 )。与部分页面一样,显示后退箭头是为了允许沿层次结构向上导航到组织项目的部分页面。与部分页面一样,用户可以通过在支持触摸的系统上使用滑动手势,或者通过与屏幕左右边缘的箭头进行交互,来选择在同一部分的详细页面之间导航。分层导航特别适合于浏览适合于主-详细分类的信息并与之交互。

图 2-12 。详细页的分层导航

许多应用不适合主从分类,这种分类适合分层导航结构,更侧重于基于文档的风格,熟悉 Microsoft Word、Excel 或 Internet Explorer。对于这种类型的应用,平面导航系统要好得多。平面导航的核心是内容被分成页面,页面上的信息要么不相关,要么在同一层级(见图 2-13 )。导航条在用户激活时出现,用于在活动文档之间切换,通常显示一个用户可以访问的命令,以将文档添加到会话中(见图 2-14 )。

图 2-13 。Internet Explorer 的设计使用整个视窗呈现单一文档的平面视图

图 2-14 。激活导航栏以切换活动文档的 Internet Explorer

字体设计

由于它非常强调排版和以文本为中心的内容,如果不提供文本格式和使用的建议,Windows 应用商店应用的用户体验指南就不完整。遵循瑞士设计的传统,在构建应用时应该使用一致的字体。应该使用哪种特定的字体取决于文本的目的。打算用于 UI 元素上的按钮或标签的文本应该倾向于 Segoe UI 字体,这在整个 Windows 8 用户界面元素中使用(参见图 2-15 )。

图 2-15 。Segoe UI 用于标签和其他 UI 元素

以只读方式呈现给读者的文本块,如新闻文章,应该倾向于使用衬线字体,因为读者习惯于用衬线字体呈现扩展的文本块(见图 2-16 )。这种字体应该以 9 磅、11 磅或 20 磅呈现,这取决于吸引焦点或显示重点的需要。这与瑞士风格在所有事情上对无衬线字体的偏好有所不同,因为微软设计团队发现在扩展阅读中衬线字体对眼睛更容易。

图 2-16 。只读文本块的 Cambria】

供用户阅读和编辑的连续块应该使用无衬线字体 Calibri(见图 2-17 )。这种字体的推荐大小为 13 磅,与 11 磅的 Segoe UI 高度相同,因此在同一行上一起使用时,两者将保持一致的外观。

图 2-17 。用于阅读编辑文本块的 Calibri】

不管字体如何,当需要强调某些文本时,强调的适当方式是通过使用与字体大小或字体粗细形成鲜明对比。在信息层次的同一层次上,权重用于强调,而大小用于区分不同的层次。使用下划线或斜体等文本装饰会降低清晰度,不应在 Windows 应用商店应用中用作强调。

其他 Windows 应用商店应用用户体验指南

在这一节中,我已经提到了一些用户体验指南,但有意地将重点放在处理应用视觉外观的指南上,将更多的行为方面留给本书其他部分讨论的主题,当我讨论开发人员可以用来构建优秀的 Windows 应用商店应用的工具时。如果你想在一个地方看到所有这些指南,或者不想等待,我建议你更深入地看看 MSDN 网站的 Windows 应用商店部分(http://msdn.microsoft/en-US/windows/default.aspx)。

Windows 8 用户界面中的微软设计语言

除了桌面模式,Windows 8 用户界面在很大程度上基于微软设计语言指南和原则。让我们从查看开始屏幕开始(参见图 2-18 )。

图 2-18 。启动屏幕并激活魅力

开始屏幕具有全屏网格,显示对用户最重要的应用(由用户选择要包含在开始屏幕中的应用来指示),并且用户从中选择他或她想要运行的应用。这假设用户想做的第一件事是运行他或她通常使用的一个应用,网格的布局是尽可能高效地完成这个非常具体的任务。通过激活应用栏(未示出),用户可以请求呈现所有应用,而不是他们更窄的收藏夹列表,从而允许用户通过额外的步骤运行安装在机器上的任何应用。如果用户不想运行某个应用,而是想执行一些其他任务,比如更改系统设置或搜索文件,用户可以激活屏幕右侧的魅力条,显示一个附加命令列表。

在本章的前面,您看到了在 Windows UI 模式下运行的 Internet Explorer 是平面导航风格的一个很好的例子。关于分层导航风格的一个例子,你可以看看 Windows 商店,那里的应用可以购买或免费下载。当您进入应用时,会显示中枢,显示可用应用的不同类别(参见图 2-19 )。

图 2-19 。Windows 商店中心页面

从该中心,用户可以直接选择某些详细信息项目,也可以选择深入查看部分页面。

在整个 Windows 8 界面以及随其提供的应用中,您可以看到一个重复出现的主题,即基于印刷字体的界面、鲜艳的颜色和动画,以确保用户认为这些应用响应迅速,并提供与其他应用和云中信息的连接。

结论

在本章中,您了解了 Microsoft 设计语言,它是 Windows 8 用户界面和 Windows 应用商店应用的基础,您了解了一些影响 Microsoft 设计语言发展的早期风格和设计范例。无论您何时构建 Windows 应用商店应用,这些概念都会保留在后台或前台,并且会影响您做出的每个设计决策。虽然本质上足够简单,以至于没有多少设计技巧的开发者也可以有效地创建这些用户界面,但是指南也提供了由视觉设计艺术和工艺领域的技术人员创建的更复杂的设计。这些熟练的设计师被鼓励更深入地钻研包豪斯、瑞士风格和微软的用户体验设计准则。

三、设计 Windows 应用商店应用

在一个完美的世界里,应用开发人员会收到清晰、简洁的文件包,上面精确地列出了他们的应用应该是什么样子,以及应该做什么。他们从那张纸开始工作,从他们的角度来看,那张纸可能是自发产生的,并产生一个工作的和有用的应用。虽然许多开发人员已经设法找到了这样一个世界,但对于大多数以写代码为生的人来说,这种安排似乎就像到达香格里拉一样遥不可及。

没有拿到完整设计的开发人员必须变得比那些将需求转化为代码的人更优秀,相反,他们必须承担我认为更加困难和有趣的软件设计任务。本章面向那些自愿或必须参与 Windows 应用商店应用设计的开发人员,旨在提供此过程中重要步骤的概述。在这篇文章中,我将介绍与决定应用应该做什么以及如何呈现给用户相关的重要概念。在这一章中,我主要关注的是收集作为设计输入的需求,因为一个完全理解应用需要解决的问题的新手设计师比一个不理解的熟练设计师能创造出更有用的应用。

收集需求、设计和构建软件有许多不同的方法。虽然我在本章中使用的一些术语可能倾向于一种或另一种方法,但我的意图是捕捉重要和相关的概念,而不管您使用什么方法(如果有的话)来构建您的软件。

沟通是关键

一位同事曾经告诉我,在应用的开发中,没有什么真理应该被认为是不证自明的。几年后,我和一个亲戚的一次谈话强化了这一点。这位亲戚以“我有个朋友在做法庭报道,需要软件帮忙”开始了一段对话。像这样的东西需要多长时间才能建成?”我开始回复:“你刚才问要多久才能建好。。。我的亲戚很快插话道,“但是我没有告诉你这个该死的东西需要做什么!”通常,像这样的对话揭示了客户心中的想法和构建软件的人所听到的之间的脱节,但在一个非典型的转折中,我的亲戚发现了许多商业伙伴不知道的东西——即,如果你想要构建一些东西,你必须清楚地传达你的要求。图 3-1 说明了这种断开,通常称为阻抗不匹配

图 3-1 。阻抗不匹配

阻抗不匹配经常导致开发人员构建所要求的而不是所需要的,其主要原因是参与该过程的每个人都非常清楚地看到自己的观点,并且无法想象其他人会以不同的方式看待事情。如果不能完全避免,阻抗不匹配可以减少,方法是在设计过程开始时,承认人们对不同主题的理解会有所不同,并致力于创造一个一切都不是理所当然的环境。

注意没有作为团队的一部分参与软件开发的开发人员仍然应该在他们的头脑中区分开发人员和用户的角色,迫使他们自己站在用户的角度来看待事情。在这里,强迫自己在心里“解释”一切,就好像试图避免阻抗不匹配一样,这将有助于发现隐藏的需求。

应用应该擅长什么?

这似乎是一个显而易见的观点,但是当开始设计你的应用时,首先要确定的是它的用途。在这一点上,细节是不必要的;只需创建一个应用的一般陈述或描述,清楚地说明应用的用途或目的。一个设计良好的应用会有一件它真正擅长的事情,尤其是 Windows Store 应用,正如你将在第十九章中了解到的,它们可以协同工作来解决比单个应用开发人员预想的更大的问题。最好使用模板语句,如“该应用将 _____ 以便 _____”来帮助您不仅关注该应用将做什么,还关注为什么该应用将做或它提供的好处。如果我正在构建一个应用来跟踪一辆车的汽油里程数,语句可能是这样的:“这个应用将计算一辆车的燃油经济性,以便我可以更好地预测我的燃油成本。”

注意一定要以一种在整个设计和开发过程中非常明显的方式记录你的应用的高级目的。这构成了应用的主干,当您决定某项功能是否属于应用时,您会经常参考它。如果它不是某种法律或监管手段所必需的,并且对应用所声明的目的没有贡献,那么它就不属于应用。

确定功能需求

一旦应用的主要目的被确定为一种指导原则,确定支持主要目的的必要需求的工作就开始了,称为功能需求。根据您正在构建的应用的类型以及参与需求过程的其他人的可用性,有几种技术可以发现或引出需求。一些更常用的技巧包括:

  • 采访 : 利益相关者,或者对正在生产的软件或者软件产生的输出或利益有某种兴趣的人,被咨询以了解他们对应用的期望和需要。在访谈过程中,利益相关者应该感到他们可以自由地表达他们的需求,而不会被告知他们不能拥有某些东西,以确保他们不会忽略提及关键需求。
  • 头脑风暴 : 利益相关者和设计团队的成员一起为需求出主意。这个会议开始于一个“一切皆有可能”的氛围中,就像在面试技巧中一样,同样的原因是不要阻止利益相关者说出他们的需求。当所有参与者可以同时在同一个房间,使用白板和便笺等工具时,头脑风暴会议通常是最有效的,但是一个训练有素的团队可以通过使用电话会议工具远程实现类似的效果。关键是让每个人都集中注意力,同时积极参与。
  • 流程映射 : 对现有流程进行遍历并完整记录,以捕捉为实现目标而执行的所有步骤。这种技术需要一个现有的过程,并且当每一个步骤都可以被仔细检查时效果最好。仅仅知道当前做了什么是不够的,但是理解每一步背后的动机以及它如何有助于实现最终目标也是至关重要的。

注意“我们总是”和“我们从来没有”是两个可以阻止组织改进的短语,除非组织愿意在需要开始一项有益的活动或结束一项没有价值的活动时加上“直到现在”。这让我想起了一个古老的故事,一个女人被她的母亲教导开始准备烤肉时,从每一端切下 1 英寸,就像她祖母所做的那样。当祖母来吃晚饭时,她注意到她的孙女正在切烤肉的末端,就问她为什么要这样做。“奶奶,你总是这样做的,”孙女回答道。老奶奶只是笑着回应道:“但是我的锅短了 2 英寸。”软件项目提供了一个很好的机会来问“为什么”,并确保类似的情况在你的组织中不存在。

评估已确定的要求

识别需求的技术都指定了不要阻止对任何涉众或团队成员来说重要或有效的需求的交流。这并不意味着每一个确定的需求都可以或者应该在最终产品中实现,只是它们都应该可以被评估。一旦确定了潜在需求的领域,下一步就是审查每个需求的适当性。适当性的决定因素简单明了。如果你能直接地(诚实地)交流满足需求对于允许应用满足它的目标是多么必要,那么这个需求就是合适的。这个规则的例外是,一些需求是由外部力量驱动的,比如契约义务和法规要求,这些需求必须被满足,而不管它们是否有助于满足应用的更高层次的目标。图 3-2 展示了用于决定是否将一个潜在需求提升为将要实现的需求的决策过程。

图 3-2 。潜在的需求到需求决策

另一个经常用来确定潜在需求是否应该提升为实际需求的度量是将项目分类为“必须拥有”、“最好拥有”或“不需要”这个想法是“必须拥有”的项目成为需求;不考虑“不需要”的项目;如果在考虑了“必须拥有”的项目之后还有额外的资源可用,那么“最好拥有”的项目也会得到考虑。这种排名模式的危险在于,太多的注意力很容易被放在“值得拥有”的项目上,导致更多的时间、精力和最终的金钱花费在成功申请实际上并不需要的项目上。对于一个没有经验丰富的项目经理的项目,建议采用图 3-2 中描述的更加严格的需求定义过程。

提示敏捷方法的实践者倾向于在所谓的用户故事中表达需求。用户故事通常采用某种形式的陈述“作为一个 _____,我需要系统 _____ 以便 _____”虽然术语用户故事是特定于某些方法的,但是识别关键涉众和每个需求的目的的想法对于任何方法都是有价值的实践。

根据应用的目的度量需求的行为不仅仅是保持应用忠实于目的的一种练习,它还旨在帮助保持驱动任何项目的三个关键因素之间的平衡,无论是构建软件还是摩天大楼。

  • 时间:为了满足组织目标,项目必须在什么时候完成?
  • :能花多少?
  • 范围:要完成的工作主体是什么?

这三个因素通常是所谓的项目管理三角、的一部分,如图图 3-3 所示。三角形是描述这些因素之间关系的一种很好的方式,因为,正如三角形的边一样,一个因素的改变不会影响其他两个因素。例如,如果有更多的资金,可能会雇用额外的开发人员,完成项目所需的时间将会缩短。通常,控制软件开发项目最简单的方法是保持对范围的严格控制。

图 3-3 。项目管理三角

在一些项目中,“必须具备”的项目不能全部符合范围,因为项目受到时间、资金或两者的限制。在这些情况下,必须对项目进行评估,以确定是否有必须实现但可以等到以后实现的项目。这种优先化过程提供了时间来真正批判性地思考需求,并且可以决定是能够产生有价值的东西,还是因为需求过程停滞而不得不放弃项目。

分解需求

一旦确定了应用满足其目标的必要需求,一个称为分解的迭代过程就开始了。软件开发中的分解是指将一个大问题分解成单独的步骤。通过迭代分解,步骤本身被分解成更小的部分,这种情况会一直持续下去,直到没有什么需要分解的了,或者直到你“完成”了。 Done 是一个有点主观的术语,但是我认为它已经达到了这样一个程度,熟悉项目的开发人员应该能够坐下来,将需求作为构建应用的蓝图。在开发人员非常熟悉他们正在解决的问题的组织中,当开发工作将由不熟悉这些问题的开发人员执行时,“完成”将不会被分解到几乎同样粒度的级别。

分解是将令人生畏的问题转化为一系列容易解决的小问题的重要方法。记住关于如何吃大象的建议:一次吃一口。

构建交互流

到目前为止,焦点已经完全集中在应用作为一个整体需要完成什么上,您应该很清楚为了满足这些需求,应用需要输入和输出什么信息。一旦确定了这些需求,您就可以将注意力转移到确定用户如何最有效地将信息输入和输出应用上。在这里,你第一次开始考虑屏幕的想法,但它仍然是一个有点模糊的概念,因为你正在试图确定什么去哪里。在设计过程的这一点上,我通常倾向于避免暗示已经决定了屏幕将如何布局以及使用何种控件的语言。我更喜欢“然后用户选择保存操作”这样的短语,而不是“然后用户点击保存按钮”这是一个细微的差别,但是它将焦点放在确定完成应用目标所需的步骤顺序,以及如何将信息组织到用户交互的屏幕上。完成这一步后,您应该对应用会有哪些屏幕以及什么会触发这些屏幕之间的移动有一个很好的想法。图 3-4 显示了一个导航图,这是一个帮助定义和记录这些流程的有用方法。在其中,您可以清楚地看到应用中预期的视图,以及用户将如何在它们之间移动。

图 3-4 。导航图

线框

一旦团队确定了应用的流程,就该处理线框了。线框是应用屏幕的低保真度草图,专注于屏幕将容纳的信息和命令,而不是担心如何使它们漂亮,并陷入美学细节中。可以在餐巾纸、白板(一定要拍照)的背面捕捉线框,或者通过 Expression Blend 中的 Visio、PowerPoint、Balsamic 或 SketchFlow 等工具捕捉线框。在这一步中,您将决定用户使用什么类型的控件来与应用进行最有效的交互。在 Windows 8 应用中,线框应该反映全屏体验,用户可以专注于内容。图 3-5 展示了一个样本线框。请注意,没有花费任何努力使它看起来像一个 Windows 应用;相反,它关注的是信息以及不同交互的结果。

图 3-5 。三维线框模型

视觉设计

在应用的线框达成一致后,一些项目团队将把线框传递给视觉设计师,视觉设计师将使用诸如微软的 Blend for Visual Studio 2012 之类的工具将线框中的想法转化为视觉上有吸引力的界面。理想情况下,设计人员将遵循微软设计语言和瑞士设计风格中的指导原则,开发出与其他 Windows 8 应用外观一致的应用。Blend for Visual Studio 可以生成基于 HTML 的项目,这些项目与 Visual Studio 兼容,因此设计人员的工作可以成为开发人员添加代码以创建成品应用的基础。

注意微软有他们 Blend 软件的多个版本。Expression Blend 可用于使用 SketchFlow 构建原型,以及构建 WPF 和 Silverlight 应用。Blend for Visual Studio 2012 随 Visual Studio 一起安装,可用于设计 Windows 应用商店应用。

大多数情况下,团队没有专门的视觉设计师。他们可能有一个比团队中其他开发人员更有设计眼光的开发人员,或者视觉设计可能只是听天由命。与某些设计范例不同,使用新的 Windows 设计准则实际上给了不喜欢艺术的开发人员一个机会来创建一个吸引人的用户界面。此外,Microsoft 在项目模板中包含内置样式,可用于帮助确保应用具有新的 Windows 外观。

结论

在这一章中,我简要介绍了设计应用的许多概念和步骤。虽然重点是团队执行流程时的情况,但是当您作为一个团队创建应用时,所有步骤都值得考虑。重要的是要记住,除了极少数例外,伟大的应用都是有意的。它们首先被定义,然后被设计,只有当这两个过程完成时,它们才被构建。Microsoft 为新的 Windows 应用商店应用提供了指导,简化了视觉设计的任务,但是为了生成适合其预期目的的应用,需求定义的工作仍然必须以尽可能彻底的方式完成。

四、Visual Studio 2012 和 Windows 应用商店应用类型

在应用开发中,集成开发环境(IDE)可以让您感觉轻松工作并专注于应用应该解决的问题,也可以让您感觉非常分心,试图找出如何在 IDE 中操作,以至于无法专注于制作软件的实际任务。随着 Visual Studio 最近几个版本的发布,微软逐渐建立起了拥有可用的最佳开发 ide 之一的声誉。甚至许多不关心为微软平台开发的开发人员也会说(如果不情愿的话)很难找到更好的开发环境。在本章中,您将了解 Visual Studio 2012,这是该系列中的最新版本。因为完整地介绍这些工具和特性需要一本独立的书,所以我将在本章中介绍一些我认为对您很好地了解环境以完成本书中的练习最重要的主题。除了了解 Visual Studio 的一般知识,您还将了解用于 Windows 应用商店应用开发的项目模板。

Visual Studio 版本

Visual Studio 通常被用来描述在微软平台上开发应用的集成开发环境,但它不是一个单一的产品,而是指整个产品线。除了免费提供的速成版,Visual Studio 2012 阵容还包括:

  • 适用于 Windows 8 的 Visual Studio 速成版 2012
  • Visual Studio 网络版速成版
  • 适用于 Windows 桌面的 Visual Studio 速成版 2012
  • 适用于 Windows Phone 8 的 Visual Studio 速成版 2012
  • Visual Studio 测试专业版 2012
  • Visual Studio 专业版 2012
  • Visual Studio 高级版 2012
  • Visual Studio 旗舰版 2012

Visual Studio 速成版 2012 每个版本都提供了一个开发针对 Microsoft 堆栈不同部分的应用的环境,并且可以在不投资于完整的 Visual Studio 2012 产品的情况下使用。visual Studio Express 2012 for Windows 8 专注于提供必要的工具来构建和测试 Windows 应用商店应用,并为在 Windows 应用商店中共享和销售您的 Windows 应用商店应用提供支持。visual Studio Express 2012 for Windows 8 足以完成本书中的练习,此版本中可用的功能将是本章讨论的重点。以下是适用于 Windows 8 的 Visual Studio Express 2012 的主要功能:

  • 对代码进行基本分析,找出可能会阻止 Windows 应用商店认证的错误或做法
  • 集成调试器
  • 运行 Windows 应用商店应用的模拟器
  • 探查器帮助识别需要调整的代码
  • 单元测试支持

除了 Visual Studio Test Professional 2012 是为应用开发组织中被分配了测试角色的人员设计的之外,Visual Studio 2012 的非速成版是为专业开发人员设计的。Visual Studio Professional 2012、Visual Studio Premium 2012 和 Visual Studio Ultimate 2012 都在应用开发的以下领域逐步增加了功能:

  • 设计
  • 建筑
  • 测试
  • 分析
  • 解决纷争

您可以在www.microsoft/visualstudio找到每个 Visual Studio 2012 版本的完整功能对比。您还可以在该网站上找到 Visual Studio Express 2012 for Windows 8。如果您尚未安装 Visual Studio 2012 版,我建议您在进一步阅读之前安装 Visual Studio Express 2012 for Windows 8。

Visual Studio 入门

首次打开 Visual Studio 2012 Express 时,会出现默认视图,如图图 4-1 所示。此时,用户界面中最重要的功能是菜单栏(图中标为 A)和起始页(标为 B)。菜单栏提供了对许多命令的访问,但是当第一次打开 Visual Studio 时,你很可能会去文件菜单(如图图 4-2 所示),在那里你会选择新建项目或打开项目。起始页提供了开发人员感兴趣的项目的链接,例如关于如何在 Visual Studio 中提高工作效率或执行某些开发任务的文章。

图 4-1 。Visual Studio 初始用户界面

图 4-2 。文件菜单

注意如果您将 Visual Studio 的设置更改为非默认设置,或者如果您使用的是 Visual Studio 的不同版本,如高级版或旗舰版,您的用户体验(如工具窗口、菜单和工具栏)可能会与本章中显示的不同。例如,当我开始使用 Visual Studio 2012 Express for Windows 8 编写这本书时,我从 Visual Studio 的不同版本导入的配置在文件菜单中有一个“新建项目…”项,而不是在文件菜单中有一个“新建”子菜单,并且在该子菜单中有一个“项目…”项。我已经将我的配置重置为 Express edition 的默认配置,因此本章和后续章节将说明 Visual Studio 2012 Express for Windows 8 的默认状态。

从文件菜单中选择新建项目,打开新建项目对话框,如图图 4-3 所示。此对话框在窗口的左侧显示按类别分组的可用项目类型。选择一个类别会在窗口的中间部分显示该类别中的项目类型列表。窗口底部是用于为项目指定名称的字段、项目在磁盘上的位置以及要创建和添加项目的解决方案的名称。本书没有涉及解决方案,所以在这一点上,我将把它们描述为同时打开和使用的相关项目的集合。默认情况下,在解决方案中创建新项目的选项是启用的,因为许多应用会将业务逻辑、数据访问代码和用于向用户提供界面的代码分离到他或她自己的项目中,以帮助创建这些职责的清晰划分。解决方案的另一个常见用途是在解决方案中有一个单独的项目来测试应用。

图 4-3 。新建项目对话框

一旦创建或打开了一个项目,就会显示附加的功能。在屏幕的右侧,解决方案资源管理器窗口(如图 4-4 中的所示)填充了您项目的文件/文件夹结构,允许您导航到项目中的任何文件,双击打开代码编辑器。图 4-5 显示default.js在代码编辑器中打开。

图 4-4 。解决方案资源管理器窗口

图 4-5 。代码编辑器

图 4-6 中的所示的属性窗口包含不同的内容,这取决于 Visual Studio 中当前选择的内容。如果当前选定的项是 HTML 文件中的控件,则显示附加到该控件的属性。如果选定项是解决方案资源管理器中的文件,则显示选定文件的属性。

图 4-6 。属性窗口

我将在本章讨论的最后一个用户界面元素是工具栏上的调试按钮,如图图 4-7 所示。此按钮用于在本地计算机、内置 Windows 8 模拟器或网络上的远程计算机中启动应用的构建和调试会话。通过激活此按钮中的下拉菜单,您可以更改应用的默认运行时环境。

图 4-7 。调试按钮

在开发过程中,我经常在我的本地机器上运行我的应用,但模拟器很方便,因为它提供了在不同分辨率下测试的能力,改变方向,在不支持触摸的显示器上模拟触摸事件,并捕捉屏幕截图,当你准备在第二十三章中向 Windows 商店提交应用时,这些将会派上用场。如果您有一台平板电脑,或任何其他机器,您想用它来调试您的应用,那么一旦您配置了远程机器和 Visual Studio 项目,使用远程机器选项是非常无缝的。你可以在http://msdn.microsoft/en-us/library/windows/apps/hh441469.aspx的 MSDN 上找到这个过程的一个很好的演示。我按照这些说明在几分钟内配置了我的 Windows RT 平板电脑进行调试。

我刚刚引导您浏览了 Visual Studio 界面,只是停下来向您展示成功使用本书所需的那些特性。我强烈建议您探索 Visual Studio 中可用的不同窗口、菜单和选项,并了解每种窗口、菜单和选项如何帮助您完成开发任务。

Windows 应用商店应用类型

在本节中,我将介绍可以使用 Visual Studio 2012 附带的项目模板创建的不同应用类型。你可以在新项目对话框中找到这些模板,分类在已安装的模板 JavaScript Windows Store 下。我将在此仅介绍这些应用类型:

  • 空白应用
  • 固定布局应用
  • 网格应用
  • 拆分应用
  • 导航应用

我将在第十八章中使用 C#语言介绍 Windows 运行时组件项目类型。

空白应用

空白应用是所有可用的 Windows 应用商店应用项目模板中最基本的。它创建的项目包括一组开始的图像,这些图像将被替换为应用徽标和闪屏的自定义图像,以及一个标准样式表和一个空白页。当您的单页应用不需要其他模板提供的布局时,这种项目类型非常适用。

固定布局应用

与空白应用一样,固定布局应用项目模板为您的 Windows 应用商店应用提供了一个非常基本的起点。事实上,空白应用和固定布局应用模板之间的唯一区别是,固定布局应用模板适用于需要固定纵横比的应用。您的应用的内容包含在一个ViewBox控件中,该控件可以缩放其内容以适应应用。

这是推荐给游戏的,因为你可以用 1366 x 768 的分辨率来设计你的场景,这在今天的平板电脑上很常见。如果设备具有不同的分辨率,您的游戏将相应地缩放,以便在所有设备上对用户显示相同的效果。

网格应用

网格应用模板提供了空白应用模板所提供的一切,但它也为应用提供了屏幕和应用代码,该应用通过不同级别的细节来浏览分层数据。该应用由三个页面组成:一个显示所有组的高级视图,其中包含每个组内项目的汇总视图(如图图 4-8 所示),一个提供有关该组的附加信息及其包含的项目列表的组详细信息页面(如图图 4-9 所示),以及一个项目详细信息页面,其中提供了该组中单个项目的最详细信息(如图图 4-10 所示)。正如您在图中看到的,这个项目模板提供了一个实际上已经为您预构建的应用,只需要您修改它以适合您的数据。

图 4-8 。默认网格应用分组项目视图

图 4-9 。默认网格应用组详细信息视图

图 4-10 。默认网格应用项目详细信息视图

拆分应用

Split App 项目模板与 Grid App 模板一样,提供了一个现成的应用,用于浏览分层数据。Grid 应用和 Split 应用的主要区别在于 Split 应用仅使用两个视图来显示信息。第一个视图如图 4-11 中的所示,显示了物品被分类到的组列表。与 Grid App 不同,这个视图只包含关于组的信息,不显示任何项目信息。选择任意组导航到该组的项目屏幕(如图图 4-12 所示),在屏幕左侧提供该组中的项目列表,在屏幕右侧显示所选项目的详细信息。

图 4-11 。默认拆分应用群组视图

图 4-12 。默认拆分应用项目视图

导航应用

导航 App 项目模板是我个人的最爱。它包括必要的组件,以支持 Windows 应用商店应用常见的导航风格,而不会在您的解决方案中填充大量不必要或过于特殊的文件。这个项目类型将是你在第九章开始构建的应用的基础,随着你学习更多可以应用到应用中的概念,你将在几个章节中继续构建。通过创建页面控件,新的屏幕被添加到你的应用中,这个过程我将在第五章的中介绍,并将在本书的其余部分继续介绍。

如果空白应用模板是一张白色打印纸,导航应用模板将是一张绘图纸——两者本质上都是空的,但其中一个提供了一些有用的结构。相比之下,Grid 应用或 Split 应用模板可能是一本涂色书中的页面,其中提供了应用的轮廓,只需填写细节。

结论

在本章中,向您介绍了 Visual Studio 2012 以及可以使用内置项目模板构建的 Windows 应用商店应用类型。为了进一步学习,请考虑 Grid 应用和 Split 应用模板,检查一些现有的 Windows 应用商店应用。您可能会惊讶于您经常看到这两种方法的组件。例如,Windows 8 安装的新闻和商店应用都采用了网格应用的方法,而邮件应用是基于拆分应用模板设计的。

五、HTML 控件

正如许多新技术一样,许多人不知道 HTML5 到底是什么。对某些人来说,这就是视频。对一些人来说,这是关于语义标签的,比如新的headernav标签。对某些人来说,这是一种让网站在移动设备上运行的新魔法。对其他人来说,它只是我们在过去几十年中所熟知和喜爱的 HTML 的下一个版本。不管你听说过什么,可以肯定地说 HTML5 不是一个单一的东西。事实上,很多被认为是 HTML5 的东西是三种东西的组合:HTML、JavaScript 和 CSS。互联网上不乏关于 HTML5 及其功能的信息。HTML5 Rocks 网站(www.html5rocks)是一个很好的资源。

如果你还不熟悉 HTML5,这一章是为你准备的。在这篇文章中,我将概述一些更常见的元素。因为我属于“HTML5 只是 HTML 的下一个版本”的阵营,所以我一般简称它为 HTML。此外,我经常将 HTML 元素称为控件,特别是当提到用户与之交互的界面元素时。

幸运的是,如果你熟悉 HTML 及其提供的控件,你会很高兴地知道所有这些知识现在都适用于 Windows 8 应用开发。我们将用于开发 Windows 8 应用的 HTML 和 JavaScript 与我们用于开发网站的 HTML 和 JavaScript 相同。也就是说,你仍然应该浏览这一章,因为它确实涵盖了一些特定于 Windows 应用商店应用开发的概念。

在开始之前,您需要创建一个 Visual Studio 项目来使用这些示例。

Visual Studio 项目

正如我在第四章中提到的,Visual Studio 有许多不同的版本。在目前可用的八个版本中,有四个可用于创建 Windows 应用商店应用。这四个是

  • 适用于 Windows 8 的 Visual Studio 速成版 2012
  • Visual Studio 专业版 2012
  • Visual Studio 高级版 2012
  • Visual Studio 旗舰版 2012

在本书中,我将使用免费速成版来讨论所有的例子。虽然其他版本为专业开发人员提供了一些额外的好处,但是您会发现使用免费的开发人员工具来构建真实世界的应用是非常可行的。

注意如果你有专业版、高级版或终极版,一定要利用它们包含的额外功能。请注意,在这些版本中,一些默认设置(如菜单项、键盘快捷键和工具栏)可能与本书中的屏幕截图和说明不同。

在接下来的几页中,我们将为本章以及第六章、 7 和 8 中将要进行的工作准备环境。我会走过去

  • 创建项目
  • 查看默认项目内容
  • 添加新页面
  • 导航到新页面

我们开始吧!

创建项目

正如在第四章中所描述的,在 Visual Studio 中有许多项目模板可用于使用 HTML 和 JavaScript 构建 Windows 8 应用。我发现,对于我的口味来说,导航应用模板达到了适当的平衡,包括足够的框架来开始一个应用,而不包括太多的“新项目膨胀”因此,让我们从基于该模板创建一个项目开始。

本书附带的源代码包括一个名为 WinJSControlsSample 的完整项目,其中包含了在第五章、第六章、第七章和第八章中使用的样本代码。你可以在本书的 press 产品页面(www.apress/9781430257790)的 Source Code/Downloads 选项卡上找到本章的代码示例。

  1. 打开 Visual Studio。

  2. Select File New Project. This will open the New Project dialog (see Figure 5-1).

    图 5-1 。新建项目对话框

  3. 在“新建项目”对话框的左侧窗格中,选择模板 JavaScript Windows Store。

  4. 选择导航应用项目模板。

  5. 为项目命名:WinJSControlsSample。

  6. 单击“确定”创建您的项目。

此时,您有了一个新项目。现在,通过按 Ctrl+F5 构建并运行它。你应该会看到类似于图 5-2 的东西。

图 5-2 。现成的导航应用

注意有几种方法可以让应用停止运行。你可以从触摸屏顶部向下滑动,或者用鼠标“抓取”应用的顶部,然后将其拖到屏幕底部。或者,您可以在键盘上按 Alt+F4。最后,如果您正在调试(即,您按了 F5 而不是 Ctrl+F5),您可以使用 Alt+Tab 返回 Visual Studio 并停止调试器。

太好了!这不是很令人兴奋,但这是一个开始。现在,让我们准备在接下来几章的示例中使用的项目。

查看默认项目内容

使用导航应用模板创建项目时,会包含许多文件。名为default.html的文件是应用的起点。Visual Studio 还创建了相应的default.cssdefault.js文件,以及一个navigator.js文件,其中包含我们导航应用的逻辑。添加了一些占位符标志图像,以及一个名为 home.html 的PageControl。在阅读本书的其余部分时,您将会看到这些文件中的大部分,所以我在这里不会深入讨论它们。

让我们首先切换您的应用,以便使用灯光主题。打开default.html并在清单 5-1 中找到代码。这一步不是必需的,但它确实使接下来几章中的截图更容易阅读。你将在第九章开始构建的应用中使用一个定制的黑暗主题。

清单 5-1。 变换主题

<title>WinJSControlsSample</title>

<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

将 CSS 参考从ui-dark.css更改为ui-light.css,然后在home.html中进行相同的更改。现在,浏览default.html并找到清单 5-2 中的代码。PageControlNavigator将是您将添加到该应用中的所有页面控件的宿主。注意这里有一个对/pages/home/home.html的引用。这是您的应用的主页,当应用启动时,它将被加载到default.html中。当您浏览整个应用时,default.html将始终可见,其他页面将动态加载到这个PageControlNavigator中。

清单 5-2。 页面控制导航器

<div id="contenthost"
data-win-control="Application.PageControlNavigator"
data-win-options="{home: '/pages/home/home.html'}"></div>

添加新页面

现在,让我们为您将在本章中看到的示例向应用添加一个新页面。

  1. Right-click the pages folder and select Add New Folder. Name the new folder htmlcontrols (see Figure 5-3).

    图 5-3 。添加新文件夹

  2. 右键单击htmlcontrols文件夹并选择添加新项目…。。这将打开“添加新项目”对话框。

  3. 选择页面控件项目。

  4. 给页面控件起一个名字:htmlcontrols

Visual Studio 现在创建了三个文件,它们共同组成了页面控件:htmlcontrols.csshtmlcontrols.htmlhtmlcontrols.js。在这一章中,你的大部分代码将进入htmlcontrols.html文件。打开htmlcontrols.html并添加form元素,如清单 5-3 所示。

清单 5-3。 添加表单

<body>
    <form id="myForm">
    <!-- SNIPPED -->
    </form>
</body>

虽然您的应用不需要,form将允许您在本章后面利用一些内置的验证和按钮功能。但是,默认情况下,当提交 HTML 表单时,表单中的数据会在请求新页面时发送到服务器。

因为您不希望在提交表单时导航到新页面,所以您修改了htmlcontrols.js,ready函数,如清单 5-4 所示。这可以防止应用离开您的页面。

清单 5-4。 防止默认表单提交

ready: function (element, options) {
    document.getElementById("myForm").addEventListener("submit", function (e) {
        e.preventDefault();
    });
},

现在,准备示例应用还有最后一件事要做:让用户导航到这个新页面。

导航到新页面

如上所述,现在应用将在启动时加载home.html。然而,您将把您的代码添加到htmlcontrols.html中。您需要提供某种方式来从一个页面导航到另一个页面。打开home.html,找到主section元素。用按钮的代码替换占位符内容,就像我在清单 5-5 中所做的那样。

清单 5-5。 新 home.html 主要内容章节

<section aria-label="Main content" role="main">
    <p><button id="htmlButton">Chapter 5 - HTML Controls</button></p>
</section>

现在,打开home.js并修改清单 5-6 中突出显示的代码。

清单 5-6。 修改为 home.js

"use strict";

var nav = WinJS.Navigation;

WinJS.UI.Pages.define("/pages/home/home.html", {
    // This function is called whenever a user navigates to this page. It
    // populates the page elements with the app's data.
    ready: function (element, options) {
        htmlButton.addEventListener("click", function (e) {
             nav.navigate("/pages/htmlcontrols/htmlcontrols.html")
        }, false);
    }
});

就这样。保存所有更改并运行应用。当应用启动时,您应该会看到一个类似于图 5-4 的页面。

图 5-4 。应用的主页

点击按钮应该会将您带到类似于图 5-5 的页面。因为您使用导航应用模板和页面控件,所以后退按钮会自动连接。单击它将返回到应用主页。

图 5-5 。htmlcontrols.html 的当前内容

控制器

HTML 已经被用来构建 web 应用很多年了。使用 HTML 和 JavaScript 构建 Windows 8 应用在许多方面与构建 web 应用相似。HTML 为构建应用提供了许多控件。在这一章中,我将快速介绍许多最常见的控件。这一章并不是对这些 HTML 控件的详尽的参考,而是对每一个控件都提供了一个简短的描述和示例用法。

注意如果你正在执行本章中的所有示例,请确保将所有的示例代码放在htmlcontrols.html<section aria-label="Main content" role="main"></section>元素之间。

标签

标签可能是我将要介绍的所有 HTML 控件中最简单的一个。默认情况下,它不会以任何方式改变其内容的外观,尽管可以用 CSS 对其进行样式化。标签通常用于使用for属性将一些文本与输入字段相关联。当标签控件的for属性与输入控件的id属性匹配时,单击或触摸该标签会选择或切换输入控件。这对可用性非常好,尤其是在使用触摸时,因为它为用户选择输入字段提供了一个更大的上下文目标。

向页面添加标签非常简单。在清单 5-7 中,您可以看到在页面上放置一个标签所需的单行代码。通过将id属性设置为"myLabel",您可以在您的 JavaScript 代码中引用这个标签,并使用 CSS 样式化标签。

清单 5-7。 添加标签

<label id="myLabel" for="myTextbox">This is text in a label</label>

for属性设置为"myTextbox"会将该标签与该页面上某处定义的另一个控件相关联。当用户点击myLabel时,myTextbox控件将被聚焦。这段代码的结果可以在图 5-6 中看到。

图 5-6 。标签

除了将文本与输入字段相关联之外,还可以考虑为其他文本使用标签,比如错误消息和其他动态用户反馈,或者甚至作为一种使文本具有样式的简单方法。虽然这在功能上是可能的,但许多人认为这在语义上是不正确的。对于这样的情况,您应该考虑使用 HTML spandiv元素,或者其他在语义上更有意义的元素。一个这样的例子可以在MessageDialog的讨论中的第六章的中看到,其中一个span元素用于动态显示用户在MessageDialog中的选择。

链接

只有一个屏幕的应用当然有用,但是通常情况下,你的应用需要多个屏幕。有几种方法可以从一个屏幕导航到另一个屏幕,但最简单的方法之一是使用 HTML 链接。

超文本链接

清单 5-8 展示了你可以添加到htmlcontrols.html中的代码,以便在页面上放置一个链接。添加这段代码,然后添加另一个名为otherpage的页面控件,遵循与创建htmlcontrols页面控件相同的步骤。这是您的链接将导航到的页面。

清单 5-8。 添加链接

<a id="myLink" href="/pages/otherpage/otherpage.html">Link to another page</a>

现在运行应用。事情看起来很好,你应该在页面上看到一个类似于图 5-7 所示的链接。点击链接将导航至otherpage.html;所以,试试吧。

图 5-7 。环

另一页看起来像你期望的那样吗?可能不会。我知道我第一次点击我正在构建的应用中的链接时,结果有点不和谐。我从otherpage.html看到了我期望的内容,但是我期望应用的格式保留在新页面上。相反,页边距和其他样式已经消失,如图 5-8 所示。

图 5-8 。另一页,但不完全是预期的

发生了什么?在前面的清单 5-2 中,您看到了default.html中实现了一个PageControlNavigator的代码。你所有的页面,比如otherpage.html,都将被加载到那个容器中——或者至少这是我所期望的。相反,点击链接会导致一个顶级导航,otherpage.html被全屏加载,取代了default.html和导航容器。事实证明,使用PageControlNavigator需要以不同的方式处理导航。

导航方法

当您从导航应用项目模板创建此应用时,您隐含地做出了这样的决定:为了应用处理页面之间的导航并提供一致的用户体验的便利性,您牺牲了使用简单链接的能力。为了让导航如您所愿,您需要一种特殊的方法在页面之间导航。Windows 8 为此提供了WinJS.Navigation.navigate方法。在清单 5-6 中已经介绍了这个方法。您向home.html添加了一个按钮,并且在home.js中,您向按钮的click事件添加了一个事件处理程序。然后当你查看home.htmlhtmlcontrols.html时,导航“刚刚工作”要让这个链接按预期工作,您只需在这里使用相同的方法。让我们从htmlcontrols.html中的链接中移除href属性(参见清单 5-9 ,让我们为htmlcontrols.js中的就绪函数添加一个链接的click事件的处理程序(参见清单 5-10 )。

清单 5-9。 改变链接

<a id="myLink">Link to another page</a>

清单 5-10。 处理链接点击事件

ready: function (element, options) {
    myLink.addEventListener("click", function (e) {
        nav.navigate("/pages/otherpage/otherpage.html")
    }, false);
},

现在如果你运行应用并点击链接,你会看到预期的结果(见图 5-9 )。页边距和后退按钮似乎对otherpage.html是正确的。事实上,back 按钮已经被连接起来,当它被点击时可以导航回htmlcontrols.html

图 5-9 。这是预料中的事

任务完成!正确嗯,从技术上来说,是的,但是如果你在一个页面上有五个链接呢?如果你的应用中有 25 个链接呢?如果您有一个从数据源动态生成的链接列表会怎么样?更新每个链接并为每个链接添加一个click事件处理程序,虽然可能,但效率不是很高。幸运的是,还有一种选择。

使用查询将 HTML 链接转换为使用 Navigate 方法

Windows 8 提供了WinJS.Utilities.query方法,该方法允许您获取与查询选择器匹配的元素集合,然后对该集合中的每个元素做一些事情。在您的例子中,您将为每个匹配链接查询的元素添加click事件处理程序(参见清单 5-11 )。

清单 5-11。 向链接集合添加事件处理程序

WinJS.Utilities.query("a").listen("click", function (e) {
    e.preventDefault();
    nav.navigate(e.target.href);
});

我将带您浏览一遍,解释每条语句的作用。函数调用WinJS.Utilities.query("a")查找当前页面上的所有链接——所有a元素。对于找到的每个链接,调用listen方法来处理click事件,并提供一个匿名函数作为事件处理程序。调用e.preventDefault会阻止默认行为,即链接的href属性中指定地址的顶级导航的发生。然后,对navigate的调用按照预期执行导航。

注意如果您熟悉 jQuery,WinJS.Utilities.query的行为与 jQuery $函数非常相似。两者都采用选择器(www.w3/TR/css3-selectors/)并返回匹配 DOM 元素的集合。如果你更喜欢 jQuery,你会很高兴知道你可以在你的 Windows 8 应用中使用它,以及 WinJS 功能。

现在你有几个选择来放置清单 5-11 中的代码。一种选择是将它放在每个页面控件的ready函数中,类似于您在home.js ( 清单 5-6 )中对按钮点击处理程序所做的。这是完全正确的,但是可能会导致几个文件有重复的代码。当您为您的项目选择导航应用模板时,Visual Studio 向js文件夹添加了一个名为navigator.js的文件,这里定义了PageControlNavigator控件。这似乎是添加您的click事件处理程序的好地方。在清单 5-12 中,我将定义一个名为NavigationUtilities的类,并将一个名为HandleLinkClickWithNavigate的静态方法添加到该类中。我将添加清单 5-11 中的代码作为HandleLinkClickWithNavigate方法的主体。

清单 5-12。 定义导航工具类

WinJS.Namespace.define("Application", {
    PageControlNavigator: WinJS.Class.define(
        // SNIPPED
    ),

    NavigationUtilities: WinJS.Class.define(
        function NavigationUtilities(element, options) { /* empty constructor */ },
        { /* no instance methods */ },
        { /* static methods */
            // change all links to use navigation methods instead
            HandleLinkClickWithNavigate: function () {
                WinJS.Utilities.query("a").listen("click", function (e) {
                    e.preventDefault();
                    nav.navigate(e.target.href);
                });
            }
        }
    )
});

现在,您必须确保在页面加载后调用此方法。如清单 5-13 中的所示,你可以通过调用htmlcontrols.jsready函数中的HandleLinkClickWithNavigate来实现。

***清单 5-13。***html controls . js 中的修改就绪函数

ready: function (element, options) {
    Application.NavigationUtilities.HandleLinkClickWithNavigate();
    document.getElementById("myForm").addEventListener("submit", function (e) {
e.preventDefault();     });
},

您必须做的最后一件事是再次添加链接的href属性,这是您之前移除的,使它看起来再次类似于清单 5-8 中的。现在,当您运行应用并单击链接时,导航按预期进行,但您还有一个额外的好处,即您添加到应用中的任何其他链接也将按预期工作。

不过,要记住的一点是,这种方法会导致所有的链接都这样。如果您有任何想要以不同方式运行的链接,您将不得不修改HandleLinkClickWithNavigate方法。一种可能是将查询从WinJS.Utilities.query("a")更改为WinJS.Utilities.query("a:not(.defaultClick)"),然后向您希望保留默认行为的任何链接添加一个 CSS 类defaultClick。有许多方法可以解决这个问题,这只是一个选项。

文本输入控件

大多数应用接受用户以某种形式输入的文本。它可能是搜索字段、登录屏幕或数据输入表单,但应用不接受文本输入的情况很少见。HTML 为文本输入提供了几种选择:单行文本输入、密码输入和多行文本输入。

单行文本输入

向应用页面添加基本文本输入是通过 HTML input元素完成的。正如你将在本章中看到的,input元素用于许多不同类型的输入,这些输入由type属性指定。也许最广泛使用的是文本输入,通常称为文本框。将清单 5-14 中的代码添加到htmlcontrols.html中,运行您的应用,您会看到一个简单的文本输入,类似于图 5-10 中所示的内容。

清单 5-14。 添加文本输入控件

<input type="text" id="myTextbox" />

图 5-10 。文本输入

该控件还有一些其他属性,可以设置这些属性来更改文本输入控件的行为。一些更常见的属性是

  • placeholder:这个属性允许你提供一些文本,用来给用户提供一些指示,通常是有效输入的一个样本。当字段为空时,文本可见,但当字段成为焦点时,文本消失。
  • maxlength:这个属性允许你指定一个文本输入控件中允许的最大字符数。这是一个简单的第一级数据验证,在用户输入最终将被保存到具有指定最大长度的数据库字段时特别有用。
  • required:这个属性表示用户必须在文本输入控件中输入一些内容才能生效。这是一个验证属性,是 HTML 提供的验证功能的一部分。
  • pattern:这个属性允许你指定一个正则表达式,用来验证用户输入到文本输入控件中的文本。这是一个验证属性,是 HTML 提供的验证功能的一部分。
  • title:这个属性允许你指定文本作为控件的工具提示。此外,如果指定了 pattern 属性,并且用户输入了无效文本,则该属性的内容也会作为错误消息的一部分显示给用户。

清单 5-15 显示了使用这些属性的简单语法。

清单 5-15。 给你输入的文本添加占位符文本

<input type="text" id="myTextbox"
    placeholder="Enter your name"
    maxlength="15"
    required
    pattern="^[A-Za-z]*$"
    title="Only characters, A-Z or a-z" />

当您运行该应用时,您将看到一个带有占位符文本的控件,如图 5-11 中的所示,您将不能在该字段中输入超过 15 个字符。此外,当用户试图提交表单时,将进行验证以确保用户输入了某些内容(由于required属性)并且只输入了字母字符(因为pattern属性只允许字母)。提交带有无效文本的表格,或者根本没有输入任何文本,将导致向用户显示一条错误消息(参见图 5-12 )。

图 5-11 。文本输入,带占位符文本

图 5-12 。文本输入,无效文本包含空格

注意虽然总是强制执行maxlength属性,但是在表单提交之前不会触发 HTML 验证。我将在本章后面的“按钮”部分讨论提交表单。关于 HTML5 提供的新表单验证功能的很棒的教程可以在www.html5rocks/en/tutorials/forms/constraintvalidation/找到。

只要用户输入有效文本,就不会显示错误消息。在图 5-13 中可以看到文本输入控件的一个新特性,这是 Windows 8 应用(以及微软的 Internet Explorer 10 网络浏览器)的一个新特性。当用户输入文本时,文本输入控件中会出现一个×按钮。单击此按钮将清除文本输入控件,以便用户可以输入新文本。

图 5-13 。有文本的文本输入,有焦点

如果您有理由隐藏这个 clear 按钮,您可以使用 CSS 来样式化-ms-clear伪元素。可以将清单 5-16 中的代码添加到default.css中,从应用的所有文本输入控件中移除清除按钮。

清单 5-16。 从文本输入控件中移除清除按钮

::-ms-clear {
    display: none;
}

密码输入

密码是另一种通常输入到应用中的文本类型,HTML 提供了密码输入控件。这些控件的行为非常类似于我刚刚提到的单行文本输入控件,但是增加了屏蔽用户输入的安全性好处,使得窥探的眼睛看不到正在键入的内容。要添加一个密码输入控件,添加从清单 5-17 到htmlcontrols.html的代码。

清单 5-17。 添加密码输入控件

<input type="password" id="myPassword" />

运行应用,你会看到一个密码字段,看起来很像一个文本输入控件(图 5-14 )。但是,默认情况下,在字段中键入不会显示您的文本。相反,它显示了在图 5-15 中看到的熟悉的黑点。

图 5-14 。密码输入

图 5-15 。带文本的密码输入(用点屏蔽)

大多数可以应用于文本输入控件的可选属性也可以应用于密码输入控件。具体来说,placeholdermaxlengthrequiredpatterntitle属性都创建了密码控件的行为,就像它们创建常规文本控件一样。

我提到密码输入控件默认不显示用户的文本。但是,与清除文本输入控件上的文本的×按钮类似,密码输入控件也有一个显示输入文本的按钮。当点击并按住按钮时,密码被显示,当松开按钮时,密码再次被圆点掩盖(参见图 5-16 )。类似于用 CSS 移除文本输入控件上的×按钮,这个按钮可以通过样式化-ms-reveal伪元素来移除。

图 5-16 。密码输入,显示密码

多行文本输入

有时,您需要比单行文本输入控件所能提供的更多的文本。使用 HTML 的textarea元素,您可以创建一个多行文本输入控件,它允许长文本和带回车的文本。将清单 5-18 中的代码添加到htmlcontrols.html中。

清单 5-18。 添加多行文本输入控件

<textarea id="myTextarea"></textarea>

这将创建最基本的多行文本输入控件,如图 5-17 所示。如果内容太大,控件容纳不下,滚动条就会出现(参见图 5-18 )。

图 5-17 。多行文本输入

图 5-18 。多行文本输入,带文本和滚动条

该控件还有一些其他属性,可以设置这些属性来更改多行文本输入控件的行为。一些比较常见的是

  • rows:这个属性允许你指定控件的高度,以文本行为单位。例如,设置rows="5"将增加上面控件的高度,使五行文本可见。多行文本输入控件的高度也可以在 CSS 中用height属性设置。
  • cols:这个属性允许你指定控件的宽度,这个宽度是根据一行中字符的大概数量来度量的。例如,设置cols="50"将增加上面控件的宽度,这样每行大约可以容纳 50 个字符。因为在大多数字体中,字符宽度不是恒定的,所以有些字符比其他字符占用更多的空间,根据内容的不同,每行的字符可能更多或更少。多行文本输入控件的宽度也可以在 CSS 中用width属性设置。
  • maxlength:这个属性允许你指定多行文本输入控件中允许的最大字符数。这是一个简单的第一级数据验证,在用户输入最终将被保存到具有指定最大长度的数据库字段时特别有用。
  • required:这个属性表示用户必须在文本输入控件中输入一些内容才能生效。这是一个验证属性,是 HTML 提供的验证功能的一部分。
  • title:这个属性允许你指定文本作为控件的工具提示。

选择控件

你想要多大的比萨饼?你的比萨饼想要哪种配料?你想在家吃饭,带走,还是叫外卖?与订购比萨饼一样,应用可以向用户提供多种选择。HTML 提供了一些用于选择的控件:下拉列表、复选框和单选按钮。

下拉列表

下拉列表可以在很小的空间内为用户提供大量的选项。让我们添加一个并尝试一下。将清单 5-19 中的代码添加到htmlcontrols.html

清单 5-19。 添加下拉列表控件

<select id="mySelect">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option selected="selected" value="option4">Option 4</option>
    <option value="option5">Option 5</option>
    <option value="option6">Option 6</option>
    <option value="option7">Option 7</option>
    <option value="option8">Option 8</option>
    <option value="option9">Option 9</option>
    <option value="option10">Option 10</option>
</select>

这段代码做了很多事情。它向页面添加一个下拉列表;它在下拉列表中添加了十个选项供用户选择;它使第四个选项成为页面加载时的默认选项(见图 5-19 )。下拉列表的默认行为是只允许一个选择,并且只显示选中的选项。点击或触摸下拉列表展开控件,向用户显示所有选项(参见图 5-20 )。如果列表太长,滚动条会自动添加。

图 5-19 。下拉列表控件

图 5-20 。展开的下拉列表控件

该控件还有一些属性,可以设置这些属性来更改下拉列表的行为。一些比较常见的是

  • selected:这是option元素的一个属性,见于清单 5-19 ,允许你指定默认选择哪些选项。如果使用了多个attribute,那么selected属性可以被添加到多个option元素中。
  • multiple:该属性允许您指定用户可以从列表中选择多个选项。这是通过在选择每个所需选项时按住 Ctrl 键来完成的。设置此属性后,列表显示为列表框,而不是下拉列表。
  • size:这个属性允许你指定列表的大小,用不需要滚动就可以看到多少选项来衡量。

在清单 5-20 中,您可以修改之前的下拉列表,以允许多重选择并一次显示五个项目。

清单 5-20。 添加允许多选的下拉列表控件

<select id="mySelect" multiple size="5">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
    <option selected="selected" value="option4">Option 4</option>
    <option value="option5">Option 5</option>
    <option value="option6">Option 6</option>
    <option value="option7">Option 7</option>
    <option value="option8">Option 8</option>
    <option value="option9">Option 9</option>
    <option value="option10">Option 10</option>
</select>

当你运行应用时,你会看到一个列表,类似于图 5-21 。您可以通过在选择选项时按住 Ctrl 键来选择多个项目(因为有了multiple属性)。

图 5-21 。下拉列表,调整大小并允许多重选择

复选框

当你需要问用户一个“是或否”的问题时,或者当有许多选项并且允许用户选择多个时,复选框是一个很好的选择。在清单 5-21 的中,你可以给htmlcontrols.html添加一个复选框。

清单 5-21。 添加复选框控件

<input type="checkbox" id="myCheckbox" />
<label for="myCheckbox">Check the box</label>

图 5-22 。复选框,未选中

注意标签的使用,当它的内容被点击或触摸时,切换复选框。默认情况下,该复选框是未选中的,如图图 5-22 所示。

该控件有几个属性,可以设置这些属性来更改复选框控件的行为。最常见的是checked属性(见清单 5-22 )。

清单 5-22。 添加复选框控件

<input type="checkbox" id="myCheckbox" checked />
<label for="myCheckbox">Check the box</label>

该属性允许您指定默认情况下复选框是否被选中(参见图 5-23 )。

图 5-23 。复选框,已选中

单选按钮

当用户需要从可能选项的简短列表中选择一个选项时,单选按钮非常有用,例如回答选择题或回答调查。在清单 5-23 中,我给htmlcontrols.html添加了两个单选按钮。每个单选按钮由一个 HTML input元素表示,其type属性设置为radio。为了更好的可用性,我再次为每个单选按钮添加了一个标签控件。

清单 5-23。 添加单选按钮

<input type="radio" id="myRadio1" name="myRadioButtonGroup" value="radio1" />
<label for="myRadio1">Option 1</label>
<input type="radio" id="myRadio2" name="myRadioButtonGroup" value="radio2" checked />
<label for="myRadio2">Option 2</label>

当您运行您的应用时,您会看到两个单选按钮(参见图 5-24 )。由于checked属性,最初选择了选项 2,您应该能够在这两个选项之间切换。每个单选按钮都有一个唯一的id属性,但是name属性是相同的。name属性用于将相关的单选按钮组合在一起,页面上的每组单选按钮都需要不同的name属性。

图 5-24 。单选按钮

选择选择控件

在决定使用哪种类型的选择控件时,应该考虑许多因素。用户是从一长串选项中选择一个选项吗?使用下拉列表。用户是从三到四个选项中选择一个选项吗?也许一系列单选按钮会更好。用户是否在回答“是或否”的问题?使用复选框。

显然,做出这个决定不仅仅是这三个简单场景中的例子。Microsoft 提供了有关如何确定控件是否适合在多种情况下使用的指南。

  • 下拉列表 : http://msdn.microsoft/en-us/library/windows/desktop/aa511458.aspx
  • 复选框 : http://msdn.microsoft/en-us/library/windows/desktop/aa511452.aspx
  • 单选按钮 : http://msdn.microsoft/en-us/library/windows/desktop/aa511488.aspx

按钮

当用户必须启动某种操作时,比如保存数据或执行搜索,您应该提供一个按钮控件。HTML 提供了三种不同类型的按钮控件,其中两种是为满足非常特殊的需求而设计的:重置按钮,用于将表单中的所有字段重置为默认值;提交按钮,触发表单的submit事件;和用于任何其他用途的标准按钮。将清单 5-24 中的代码添加到htmlcontrols.html中。

清单 5-24。 添加按钮控件

<button type="button" id="myButton">Button</button>
<button type="reset" id="myReset">Reset</button>
<button type="submit" id="mySubmit">Submit</button>

运行应用查看按钮,如图 5-25 所示。

图 5-25 。小跟班

虽然您的按钮通常只包含纯文本,但也允许按钮包含其他更丰富的内容类型,如图像或格式化文本。例如,在清单 5-25 中,你可以创建一个包含松鼠图像和一些格式化文本的按钮。

清单 5-25。 添加更丰富的按钮

<button type="button" id="myButton">
    <img src="/img/60/Squirrel.png" /><br />
    Click the <em>squirrel</em>!
</button>

你的松鼠按钮可以在图 5-26 中看到。

图 5-26 。富按钮

注意松鼠图像可以在 WinJSControlsSample 项目中找到,该项目包含在本书附带的源代码中。你可以在本书的 press 产品页面(www.apress/9781430257790)的 Source Code/Downloads 选项卡上找到本章的代码示例。

复位按钮

重置按钮是最简单的,所以我从它开始。当按钮控件的type属性设置为reset时,按钮被赋予默认功能,该功能会将表单中所有其他字段的值更改为初始值。因为这个行为是自动分配的,所以不需要处理重置按钮的click事件;但是,表单中必须有一个重置按钮,此默认行为才能起作用。在这一章的开始,在清单 5-3 (这里在清单 5-26 中重复)中,我给htmlcontrols.html添加了一个form来允许这个例子工作。

清单 5-26。 添加表单

<body>
    <form id="myForm">
    <!-- SNIPPED -->
    </form>
</body>

运行应用,在前面添加的文本输入控件中输入一些文本。现在单击 reset 按钮,文本将被清除。

提交按钮

按钮控件被赋予默认行为的另一个例子是当它的type属性被设置为submit时。在这种情况下,点击或触摸按钮将通过触发表单的submit事件来提交表单。提交按钮在默认情况下也有不同的样式,如图 5-25 所示。此外,提交按钮是页面上的默认按钮,例如,如果在光标位于单行文本输入字段时按下 Enter 键,则表单被提交。与 reset 按钮一样,submit 按钮必须在表单中,默认行为才能起作用,并且您不需要处理它的click事件;但是,您可以选择处理表单的submit事件。

实际上,这正是你之前在清单 5-4 中所做的(在清单 5-27 中重复)。在这种情况下,您只需通过调用preventDefault函数来取消表单提交。在本书的后面,我将向submit事件添加更多的功能,以便在提交表单时做更多有趣的事情。

清单 5-27。 防止默认表单提交

ready: function (element, options) {
    document.getElementById("myForm").addEventListener("submit", function (e) {
        e.preventDefault();
    });
},

标准按钮

标准按钮是当你将按钮控件的type属性设置为button时 HTML 所提供的,它用于启动某个动作。虽然“重置”按钮和“提交”按钮各有其特定的用途,但“标准”按钮则用于其他用途。事实上,您也可以使用标准按钮来提交或重置表单。但是,您将失去使用这些专用按钮所带来的默认行为的好处。当在你的页面上使用一个标准按钮时,你将把你的功能添加到按钮的click事件中。这就是你在清单 5-6 中看到的,我在home.html的按钮上添加了一个click事件处理程序。

进度指标

进度指示器控件为用户提供有关某个操作或进程状态的视觉反馈。它可用于指示用户正处于向导中五个步骤的第三步,或者提供关于多文件下载的反馈。Windows 8 应用可以用三种不同的方式显示进度指示器:确定条、不确定条和不确定环。

确定条

当剩余工作量或剩余时间已知时,使用确定的条形图。这个指示器让用户看到你的应用取得了多大的进展。它显示为一个条形,当工作完成时,颜色从左向右变化,直到工作完成,条形被填满。要添加一个确定的进度条,添加清单 5-28 中的代码到htmlcontrols.html

清单 5-28。 添加确定的进度条控件

<progress id="myProgressDeterminate" value="75" max="100" />

指定valuemax属性会添加一个填充了 75%的进度条。你可以在图 5-27 中看到这一点。

图 5-27 。进度指示器,确定条

不定杆

当剩余工时或时间量未知时,使用不确定条形图。该指示器显示为点从左向右滚动的重复动画。当操作或流程正在进行时,用户仍然可以与您的应用交互时,通常会使用此指示器。要添加一个不确定的进度条,将清单 5-29 中的代码添加到htmlcontrols.html中。

清单 5-29。 添加一个不确定的进度条控件

<progress id="myProgressIndeterminateBar" />

因为没有指定valuemax属性,这增加了在图 5-28 中看到的动画进度条。

图 5-28 。进度指示器,不确定条形图

不定环

当剩余工作量或时间未知时,使用不定环。该指示器显示为圆点在圆圈中旋转的重复动画。当操作或流程正在进行时,如果不允许用户与您的应用进行交互,通常会使用此指示器。要添加一个不确定的进度环,添加清单 5-30 中的代码到htmlcontrols.html

清单 5-30。 添加一个不确定进度环控件

<progress id="myProgressIndeterminateRing" class="win-ring" />

就像不确定条一样,没有指定valuemax属性。在这种情况下,增加了 Windows 8 提供的特殊的“win-ring”CSS 类,这样就增加了图 5-29 中看到的动画进度环。

图 5-29 。进度指示器,不定环

结论

在这一章中,你学习了 HTML 提供的一些更常见的控件。如果您是 web 开发人员,那么您可能已经在 web 应用中见过所有这些控件。多年来,这些控件一直被用于构建 web 应用,许多有用的 Windows 8 应用都可以仅使用这些控件来构建。在第六章和第七章,我将讨论 Windows 8 提供的额外控制,使你的应用看起来和感觉起来像 Windows 8 应用。

六、WinJS 控件

在第五章的中,我介绍了一些常见的 HTML 控件,它们可以在用 HTML 和 JavaScript 构建的 Windows 8 应用中使用。如果你有 web 开发的背景,你可能对我在第五章中提到的内容很熟悉。在接下来的几章中,我将介绍 WinJS 中包含的各种控件。

在这一章中,我将介绍你可能在任何你可能构建的应用中使用的最常见的 WinJS 控件。本章中的控件将允许您以与 Windows 8 其余部分一致的方式构建导航、用户输入和用户反馈机制等内容。

在第七章的中,我将介绍ListViewFlipViewSemanticZoom控件,它们是用来处理对象集合的。这些控件允许您定义用于显示集合中每一项的模板。如果你有一个复杂的用户界面,你想在你的应用中多次使用,那么第八章就是为你准备的。您将发现如何使用 WinJS 构建自己的自定义控件。

但是在我深入研究 WinJS 和它为控件创建的所有选项之前,我将首先介绍 WinJS 实际上是什么。

WinJS、WinRT、Windows RT 和 Windows 8

2012 年,微软发布了名为 Windows 8 的新操作系统。你当然知道,否则你不会读这本书。在发布 Windows 8 的同时,微软发布了另一款新的操作系统,名为 Windows RT. Windows RT 专门设计用于基于 ARM 的设备,如平板电脑。

Windows 8 和 Windows RT 有一些关键的区别,最显著的两个区别是

  • Windows RT 无法运行为早期版本的 Windows 构建的应用。
  • Windows RT 运行在采用 ARM 处理器的设备上,而 Windows 8 运行在支持 Windows 7 的相同的熟悉硬件架构上。

抛开差异不谈,Windows 8 和 Windows RT 确实有很多共同点。Windows 8 和 Windows RT 的一些共享功能包括

  • 带有磁贴布局的开始屏幕
  • 使用“动态磁贴”向用户呈现丰富的个性化信息
  • 微软设计语言的使用,在第二章中讨论
  • 运行 Windows 应用商店应用的能力

因为这本书是关于创建 Windows Store 应用的,所以你会很高兴地知道,你使用这些概念构建的任何应用都可以在 Windows 8 和 Windows RT 设备上工作。事实上,我展示的所有代码都经过了两种操作系统的测试:我笔记本电脑上的 Windows 8 和 Surface 平板电脑上的 Windows RT。因此,除非特别指出,否则,每当我在本书中提到 Windows 操作系统时,我指的是 Windows 8 和 Windows RT。

Windows 提供了两个不同的库,用于使用 HTML 和 JavaScript 构建 Windows 应用商店应用。第一个是 Windows 运行时,通常称为 WinRT。Windows 运行时是 Windows 8 和 Windows RT 所共有的,它可以用于构建多种语言的 Windows 应用商店应用。例如,除了 HTML 和 JavaScript 之外,Windows 运行时还支持用 C#、VB.NET 和 C++构建应用。WinRT 提供了构建 Windows 应用商店应用的所有核心功能,例如应用模型、对设备和设备上的传感器的访问、网络、安全性和存储。

Windows 提供的第二个库是用于构建 HTML 和 JavaScript 的 Windows 商店应用的 Windows 库,即 WinJS。WinJS 是 JavaScript 和 CSS 代码的集合,用于简化 Windows 应用商店应用开发。所提供的 CSS 确保,默认情况下,您的应用看起来和感觉起来都像 Windows 应用商店应用,而不是网站。JavaScript 提供了许多 UI 控件,我将在本章后面讨论,还有动画和导航类、DOM 操作、事件以及创建自定义类和控件的能力。

不幸的是,在我看来,给产品命名不是微软的强项之一。正如我将在本书中介绍的,Windows 运行时通常被称为 WinRT,这个名字与 Windows RT 操作系统非常相似。更令人困惑的是,WinRT 提供的类和功能在Windows名称空间中,尽管 WinJS 提供的功能很方便地在WinJS 名称空间中。虽然对于不太熟悉的用户来说,这可能会令人沮丧和困惑,但实际上,这并不是一个问题。

控制器

WinJS 提供了许多用于在 Windows 8 应用中显示和编辑信息的控件。与第五章的中讨论的 HTML 控件类似,WinJS 控件通常是通过在 HTML 文件中添加一些标记来创建的,并且控件在添加到 HTML 中后能够在 JavaScript 中操作。因为 WinJS 控件不是 HTML 的一部分,所以它们没有可以添加到 HTML 文件中的相应 HTML 元素。相反,您使用一个div元素的data-win-control 属性来指定您想要创建的 WinJS 控件的类型。此外,因为 WinJS 控件没有专用的 HTML 元素,所以它们没有用于在 HTML 文件中设置属性的专用属性。相反,如果某些属性需要初始值,可以使用data-win-options 属性。在接下来的几页中,当我讨论不同的 WinJS 控件时,您将看到这一切是如何工作的。

在开始之前,您需要一个地方来放置本章中的代码。从第五章中打开 WinJSControlsSample 项目。在pages文件夹中创建一个名为windowscontrols的新文件夹,然后添加另一个名为windowscontrols.html的页面控件,遵循在第五章中添加htmlcontrols.html页面控件时使用的步骤。当你完成后,你的解决方案浏览器应该看起来像图 6-1 。

图 6-1 。添加一个名为 windowscontrols.html 的新页面控件

确保将windowscontrols.html 中的 CSS 引用从ui-dark.css更改为ui-light.css,并为home.html添加一个按钮和相应的点击事件处理程序,以导航到这个新页面。完成后,运行应用以确保目前为止一切看起来和运行起来都像预期的那样(参见图 6-2 )。

图 6-2 。带有新按钮的主页

注意如果你正在执行本章中的所有示例,请确保将所有示例代码放在windowscontrols.html,<section aria-label="Main content" role="main"></section>元素之间,除非特别指定了不同的位置。一个经验法则是,如果控件在屏幕上总是可见的,比如一个DatePicker,你可以把它添加到主section中。如果它只在用户执行一个动作时显示,比如从屏幕边缘滑动以看到一个AppBarSettingsFlyout,它可能需要被定义为页面的body元素中的一个顶级元素,或者可能在一个完全独立的文件中。

当你完成本章的练习时,你会看到 WinJS 控件被添加到使用 HTML 元素的页面中,通常是一个div元素,用属性定义控件的类型(data-win-control)和它的初始状态(data-win-options)。默认情况下,在屏幕上显示应用的 HTML 呈现引擎不知道任何有关 WinJS 控件的信息。它只理解 HTML、CSS 和 JavaScript。只有在调用 WinJS 方法WinJS.UI.processAll时,才会将 HTML 转换成 WinJS 控件。该方法在 HTML 文件中查找任何 WinJS 控件,并实例化它们,以便 HTML 呈现引擎可以理解它们。

您必须确保在您的应用中调用了WinJS.UI.processAll方法 。因为PageControl自动调用processAll,并且您在这些例子中使用了PageControl,您将不必手动添加这个方法调用。如果你添加任何 WinJS 控件到任何其他不是PageControl的 HTML 页面,你将不得不在你的 JavaScript 代码中显式调用该方法。

AppBar 和 AppBar 命令和

AppBar控件 用于将应用工具栏或应用栏添加到您的页面中。默认情况下,应用栏是隐藏的,直到用户通过以下方法之一激活它:

  • 用鼠标右键单击
  • 从触摸屏底部向上滑动或从触摸屏顶部向下滑动
  • 按下键盘上的 Windows 徽标键+Z

也可以通过编程激活AppBar控件,例如,通过单击应用中提供的按钮。

应用栏包含命令按钮,用户可以单击这些按钮来执行不同的操作。它分为两个部分:“全局”部分和“选择”部分。“选择”部分中的命令适用于当前选定或活动的一个项目或一组项目,如列表中的选中项目,而“全局”部分适用于当前页面。对于从左向右阅读的语言,如英语,全局部分在应用栏的右侧,选择部分在左侧。对于从右向左阅读的语言,情况正好相反。让我们给你的新页面添加一个AppBar控件。添加该控件的代码必须直接包含在页面的body元素中,所以将来自清单 6-1 的代码添加到windowscontrols.html中的开始body元素之后。

清单 6-1。 添加一个 AppBar

<body>
    <div id="myAppBar" class="win-ui-dark" data-win-control="WinJS.UI.AppBar">
        <button
            data-win-control="WinJS.UI.AppBarCommand"
            data-win-options="{id:'myAddCommand',label:'Add',icon:'add',
                section:'global',tooltip:'Add item'}">
        </button>
        <button
            data-win-control="WinJS.UI.AppBarCommand"
            data-win-options="{id:'myRemoveCommand',label:'Done',icon:'accept',
                section:'selection',tooltip:'Mark item done'}">
        </button>
        <hr
            data-win-control="WinJS.UI.AppBarCommand"
            data-win-options="{type:'separator',section:'selection'}" />
        <button
            data-win-control="WinJS.UI.AppBarCommand"
            data-win-options="{id:'myDeleteCommand',label:'Delete',icon:'delete',
                section:'selection',tooltip:'Delete item'}">
        </button>
    </div>
    <!-- SNIPPED -->
</body>

让我们深入了解一下这是怎么回事。由于data-win-control属性,WinJS 库将div元素识别为AppBar控件,并且将class属性设置为win-ui-dark将会以深色显示AppBar,默认为黑色,使其在应用的浅色背景下非常突出。我将在第九章中说明如何用颜色来设计你的应用。

接下来,向AppBar添加几个按钮和一个分隔符,将data-win-control属性设置为WinJS.UI.AppBarCommand 。此外,因为 HTML 中没有AppBarCommand元素,因此也没有与之对应的标准 HTML 属性,所以我使用data-win-options属性来设置按钮的初始属性。在第一个按钮中,我将icon属性设置为add,它显示一个加号(见图 6-3 ),我将section属性设置为global,使其显示在AppBar的右侧。想象一个任务列表应用。在这种情况下,第一个按钮会向列表中添加一个新任务。我在选择部分添加了第二个和第三个按钮。在任务列表应用中,这些按钮将应用于当前选定的任务。

图 6-3 。一个应用栏,有两个选择命令和一个全局命令 ??

注意虽然没有什么可以阻止你向选择部分添加一个全局命令,反之亦然,但随着你的用户获得 Windows 8 应用的专业知识,他们会希望按钮以这种方式组织。

你可能想知道AppBarCommand的图标是在哪里定义的。默认情况下,可用图标是使用 Segoe UI 符号字体 ?? 显示的不同字符。WinJS 在WinJS.UI.AppBarIcon枚举中提供了一个可用图标列表。通过指定其中一个作为icon属性的值,您可以显示您选择的图标。这个列表中有将近 200 个图标,完整的列表可以在微软的 MSDN 网站 ( http://msdn.microsoft/en-us/library/windows/apps/hh770557.aspx)上看到。有了这么多可用的图标,您很可能会在列表中找到一个符合您需要的图标。然而,有时你需要一些不同的东西。在这些情况下,可以提供自定义图像来代替基于字体的图像。我们将在第十二章中了解如何做到这一点。

AppBarAppBarCommand类有许多不同的属性和可用。一些比较常见的是

  • layout:这个AppBar属性允许你指定你正在提供一个应用栏的自定义布局,并且 WinJS 不应该期望显示一系列的AppBarCommand对象。
  • placement:这个AppBar属性允许你指定它应该放在页面的顶部还是底部。在屏幕顶部放置带有自定义布局的应用栏是在应用中提供导航选项的常用方式。
  • sticky:这个AppBar属性可以用来表示当用户点击或触摸应用中的其他地方时,应用栏仍然可见。用户仍然可以使用通常会激活它的相同方法隐藏应用栏,例如从屏幕顶部滑动或用鼠标右键单击。
  • disabled:这个AppBarCommand属性可以用来使一个命令对用户不可用。例如,如果在前面的任务列表示例中没有选择任何项目,则应该禁用删除命令。
  • type:该AppBarCommand属性用于改变用户将看到的命令类型。您在代码示例中简要地看到了这一点,其中您将一个命令的type属性设置为separator。该属性的有效选项有button(如果未指定,则为默认值)、separatortoggleflyout。切换命令是当用户重复选择它时在两种状态之间交替的命令按钮,例如电子邮件应用中的“标记为已读”/“标记为未读”按钮。一个弹出命令被用来显示一个Flyout控件,我将在本章后面介绍它。

在 MSDN 上可以找到AppBar ( http://msdn.microsoft/en-us/library/windows/apps/br229670.aspx)和AppBarCommand ( http://msdn.microsoft/en-us/library/windows/apps/hh700497.aspx)酒店的完整列表。

工具提示

我在第五章中简单提到了工具提示。如果您不熟悉工具提示,它们是当您将鼠标悬停在页面上的另一个控件上时显示的小文本框。它们通常包含鼠标悬停项目的描述或如何处理该项目的说明。对于大多数 HTML 控件,可以通过将title属性的值设置为想要在工具提示中显示的文本来添加简单的工具提示。将清单 6-2 中的代码添加到windowscontrols.html中。这段代码将产生一个简单的纯文本工具提示,如图 6-4 所示。

清单 6-2。 给标签添加简单的工具提示

<label title="This is a simple, text only tooltip">This label has a simple tooltip.</label>

图 6-4 。您的示例应用(正如它将在本章末尾看到的那样),突出显示了一个带有简单工具提示的标签

像这样简单的工具提示对改善用户体验大有帮助,因为他们开始了解你的应用。但是,如果您想提供更丰富的内容,WinJS 提供了一个可以包含格式化内容的Tooltip控件。将清单 6-3 中的代码添加到windowscontrols.html中,并再次运行应用。

清单 6-3。 给标签添加内容丰富的工具提示

<label id="myRichTooltip" data-win-control="WinJS.UI.Tooltip"
    data-win-options="{infotip: true,
        innerHTML: 'Here is a <strong>richer</strong> <em>tooltip</em>.'}">
    This label has a rich tooltip.
</label>

注意工具提示(见图 6-5 )实际上包含了格式化的 HTML 内容。此外,infotip属性用于指示这个可能包含大量信息的Tooltip应该比常规的Tooltip显示更长的时间。

图 6-5 。带有丰富工具提示的标签

如果您需要一个更丰富的工具提示,包含图像或其他控件,您可以利用contentElement属性创建一个工具提示,使用一个单独的 HTML 元素的内容作为您的Tooltip的内容。在 MSDN ( http://msdn.microsoft/en-us/library/windows/apps/br229763.aspx)上可以找到Tooltip控件的完整属性列表,包括contentElement属性的文档。

日期选择器 和时间选择器

如果您正在构建一个需要用户提供日期的应用,比如安排约会,您首先想到的可能是使用文本输入控件。您当然可以这样做,提供一个正则表达式模式,只允许输入格式正确的日期。在许多情况下,这可能就足够了,甚至是更好的选择。但是,至少有两个原因可以考虑使用专用的日期控件。

  • 随着触摸屏设备的日益普及,您的用户可能更喜欢用手指选择日期,而不是在键盘上键入日期。
  • 如果您的应用要在国际上使用,您必须为应用的每个本地化版本提供不同的正则表达式。

如果您有一个使用文本输入的好理由,那么前面的两个要求都不是您无法克服的障碍。然而,WinJS 提供了一个DatePicker控件来为您处理这些需求。将清单 6-4 中的代码添加到windowscontrols.html的主要内容section中。

清单 6-4。 添加日期选择器

<div id="myDatePicker" data-win-control="WinJS.UI.DatePicker"></div>

如果你的用户除了日期之外还必须输入约会的时间,你可能不会惊讶地发现 WinJS 也为这些目的提供了一个TimePicker控件,而且添加起来也很简单。将清单 6-5 中的代码添加到windowscontrols.html中。

清单 6-5。 添加时间选择器

<div id="myTimePicker" data-win-control="WinJS.UI.TimePicker"></div>

现在,当您运行您的应用时,您应该会看到如图图 6-6 所示的控件。

图 6-6 。DatePicker 控件和 TimePicker 控件

DatePickerTimePicker类有许多不同的属性可用。一些更常见的DatePicker属性有

  • current:这个属性允许你指定默认日期,当DatePicker控件最初加载时显示。如果没有为此属性指定值,默认日期将是当前日期。
  • minYearmaxYear:这些属性允许您指定用户在选择日期时可以指定的最早和最晚年份。minYear的默认值是当前年前 100 年,maxYear的默认值是当前年后 100 年。
  • yearPatternmonthPatterndatePattern:这些属性允许你控制日期不同部分的格式。例如,将datePattern属性设置为"{day.integer(2)} - {dayofweek.full}"将导致日期下拉列表将每个日期显示为两位数的日期,以零开头,后跟星期几。

在 MSDN ( http://msdn.microsoft/en-us/library/windows/apps/br211681.aspx)上可以找到DatePicker控件属性的完整列表,包括yearPatternmonthPatterndatePattern属性的选项列表。

一些更常见的TimePicker属性是

  • current:这个属性允许你指定TimePicker控件最初加载时显示的默认时间。如果没有为此属性指定值,默认时间将是当前时间。
  • clock:该属性允许您指定时间以 12 小时格式(12HourClock)或 24 小时格式(24HourClock)显示。如果使用 24 小时制,则不会显示用于选择时间段(上午或下午)的下拉列表。
  • minuteIncrement:该属性允许您限制时间的分钟部分的选择。例如,如果您正在编写一个安排牙科预约的应用,您可以将该值设置为 15,使分钟下拉列表只提供 00、15、30 和 45 作为选择。
  • hourPatternminutePatternperiodPattern:这些属性允许你控制时间不同部分的格式。例如,将hourPattern属性设置为“{hour.integer(2)}”将导致小时被格式化为两位数,如果需要的话,带有前导零。

在 MSDN ( http://msdn.microsoft/en-us/library/windows/apps/br229736.aspx)上可以找到TimePicker控件属性的完整列表。

切换开关

如果你使用 Windows 8 有一段时间,你可能会看到一个ToggleSwitch(见图 6-7 )。

图 6-7 。基本的拨动开关

很像一个复选框,它被用来在两种可能的状态之间切换,允许你的用户做出诸如“开和关”、“是或否”、“真或假”、“喜欢它或讨厌它”等选择。在清单 6-6 的中可以看到ToggleSwitch的最简单用法。

清单 6-6。 添加 ToggleSwitch

<div id="myToggle" data-win-control="WinJS.UI.ToggleSwitch"></div>

ToggleSwitch类有许多不同的属性可用。一些比较常见的是

  • title:该属性允许您指定在ToggleSwitch上方显示的文本提示。如果未指定title,则不显示提示。
  • labelOnlabelOff:这个属性允许你指定当用户打开和关闭控件时显示的文本。默认情况下,labelOn设置为On,,而labelOff设置为Off
  • checked:该属性允许您指定页面加载时ToggleSwitch的初始状态。默认情况下,checked为假,ToggleSwitch关闭。

在 MSDN ( http://msdn.microsoft/en-us/library/windows/apps/hh701411.aspx)上可以找到ToggleSwitch控件属性的完整列表。为了查看这些属性如何影响ToggleSwitch,让我们用下面的清单 6-7 中的代码替换清单 6-6 中的代码。

清单 6-7。 增加一个更有价值的 ToggleSwitch

<div id="myToggle" data-win-control="WinJS.UI.ToggleSwitch"
    data-win-options="{title:'What do you think about pizza?',
        labelOn:'Love it',
        labelOff:'Hate it',
        checked:true}"></div>

看完代码后,您可能不会惊讶地发现您的应用现在看起来像图 6-8 。

图 6-8 。您定制的 ToggleSwitch

正如我提到的,一个ToggleSwitch的行为非常像一个复选框。两者都允许你打开或关闭某些东西。微软提供了关于ToggleSwitch用法(http://msdn.microsoft/en-us/library/windows/apps/hh465475.aspx)的指导,包括以下关于在ToggleSwitch和复选框之间选择的建议:

  • 当更改将立即生效时,使用ToggleSwitch,例如在SettingsFlyout中。
  • 如果在用户执行其他操作(如单击提交按钮)之前,更改不会生效,请使用复选框。
  • 当用户可以从列表中选择多个项目时,使用复选框。

基于这个指导,虽然它说明了一些不同属性的用法,但是图 6-8 中的例子可能不是ToggleSwitch控件的最佳用法。用户可以通过Rating控件得到更好的服务。

评级

使用Rating控件,您可以提供一个熟悉的机制来对事物进行评级。显示为熟悉的一系列星星,Rating控件是收集关于某样东西质量的反馈的直观方式。将清单 6-8 中的代码添加到windowscontrols.html中,然后运行您的应用。

清单 6-8。 添加一个评级控件

<div id="myRating" data-win-control="WinJS.UI.Rating"></div>

当页面第一次加载时,你会看到一系列类似于图 6-9 的五星。除了这个视图之外,Rating控件的另外两个视图也是现成的:暂定评级视图和用户评级视图。当您将鼠标悬停在每个评级星上方时,将显示暂定评级视图。当你将鼠标悬停在每个星星上时,星星的颜色会动态变化,工具提示会显示你选择该选项时所设置的值(参见图 6-10 )。当您最终选择其中一颗星星时,颜色变化被设置,工具提示被隐藏(参见图 6-11 )。

图 6-9 。标准分级控制

图 6-10 。当用户的鼠标悬停在第四颗星星上时的暂定评级

图 6-11 。用户选择的评级

Rating类有许多不同的属性可用。一些比较常见的是

  • maxRating :该属性允许您指定用户可以选择的最大可能等级。默认情况下,maxRating设置为 5。
  • averageRating :此属性允许您指定用户对该物品的平均评分。确定该平均值的方法由您决定,而不是由Rating控件提供。
  • tooltipStrings :该属性允许您指定当用户将鼠标悬停在Rating控件中的每个选项上时显示的工具提示。该属性接受一个字符串数组,数组中的项数必须与maxRating属性的值相匹配。默认情况下,tooltipStrings为空,数字显示在每个选项的工具提示中。
  • disabled :该属性允许你指定Rating控件处于只读状态。当disabled属性设置为true时,用户不能添加或更改等级。

在 MSDN ( http://msdn.microsoft/en-us/library/windows/apps/br211895.aspx)上可以找到Rating控件属性的完整列表。为了看看这些属性是如何影响Rating的,让我们用下面清单 6-9 中的代码替换清单 6-8 中的代码。

清单 6-9。 更好的披萨评分界面

<div id="myRating" data-win-control="WinJS.UI.Rating"
    data-win-options="{averageRating:3.6,
        tooltipStrings:['Hate it','Dislike it','It\'s Ok','Like it','Love it']}"></div>

现在,当您运行应用时,您会看到一个更适合测量人们对比萨饼的喜爱程度的控件。同样的五颗星也在那里,但是它们将被突出显示以指示averageRating属性的当前值。在这个例子中,3.6 颗星星被高亮显示(见图 6-12 )。

图 6-12 。具有平均评级的评级控制

当您将鼠标悬停在不同的星星上时,您可以看到为tooltipStrings属性指定的不同值(参见图 6-13 )。此外,当您将鼠标悬停在星星上时,它们会以不同的颜色突出显示,默认情况下为蓝色。

图 6-13 。每个选项的自定义工具提示

消息对话框

如果你已经编写或使用软件一段时间了,你肯定对消息框很熟悉。通常显示为模式窗口,即应用前面的窗口,它阻止应用在被寻址之前使用,消息框用于向用户显示紧急信息,或者请求应用继续使用所需的信息。对于 Windows Store 应用,您可以使用MessageDialog控件来实现这一目的。

注意MessageDialog控件实际上是由 Windows 运行时 WinRT 提供的,并不是 WinJS 的一部分。

添加一个对话框比我之前讨论的一些控件要复杂一些,但是仍然非常简单。对于您的示例,您将向页面添加一个按钮,用于打开MessageDialog控件,尽管在实践中,您可以基于任意数量的标准创建MessageDialog。首先将清单 6-10 中的代码添加到windowscontrols.html中。

清单 6-10。 添加一个按钮显示消息对话框和一个占位符显示结果

<button id="myShowDialogButton">Show message</button>
<span id="myDialogResult"></span>

现在,您需要让按钮在用户单击它时做一些事情。将清单 6-11 中高亮显示的代码添加到windowscontrols.js中的ready函数中。这段代码将导致一个名为myShowDialogButton_Click的函数,当有人点击这个按钮时,这个函数就会被执行。

清单 6-11。 为按钮点击接线起事件处理程序

ready: function (element, options) {
    // message dialog event binding
    document.getElementById("myShowDialogButton")
        .addEventListener("click", myShowDialogButton_Click, false);
},

现在让我们创建一个函数,它将实际处理按钮点击并向用户显示MessageDialog。清单 6-12 包含前面提到的myShowDialogButton_Click函数的函数定义。务必注意这段代码在windowscontrols.js中的位置。该功能应在PageControl定义后定义。为了帮助澄清这一点,清单 6-12 还包括了PageControl 的定义,但是为了简单起见,删除了其中的内容。

清单 6-12。 在 PageControl 定义后添加事件处理程序

"use strict";

WinJS.UI.Pages.define("/pages/windowscontrols/windowscontrols.html", {
    // SNIPPED
});

function myShowDialogButton_Click() {
    // Create the message dialog and set its content
    var msg = new Windows.UI.Popups.MessageDialog("Some irreversible process is about to "
        + "begin. Do you wish to continue?", "Message dialog sample");

    // Add commands and set their command handlers
    msg.commands.append(new Windows.UI.Popups.UICommand("Continue", function (command) {
        myDialogResult.textContent = "You chose 'Continue'";
    }));

    msg.commands.append(new Windows.UI.Popups.UICommand("Cancel", function (command) {
        myDialogResult.textContent = "You chose 'Cancel'";
    }));

    // Set the command that will be invoked by default
    msg.defaultCommandIndex = 0;
    msg.cancelCommandIndex = 1;

    // Show the message dialog
    msg.showAsync();
}

清单 6-12 中定义的事件处理器创建一个MessageDialog对象。在向用户显示之前,您创建两个UICommand对象并将它们添加到您的MessageDialog中。当显示MessageDialog时,这些命令是用户可以选择的按钮。在这种情况下,您可以通过设置清单 6-10 中占位符的textContent属性来处理每个按钮的点击。

注意如果你的事件处理程序很短,你可以省去一个单独的事件处理函数。相反,您可以使用匿名函数在对addEventListener的调用中声明click事件处理程序。你可以在清单 6-12 中看到这种技术,这里我定义了MessageDialog对象的命令按钮。虽然匿名函数在这个例子中也可以工作,但是长的处理程序会使代码更难阅读。

一个MessageDialog可以定义一个默认命令和一个取消命令。默认命令是当用户按下 ENTER 键时将被单击的按钮。“取消”命令是用户按下 ESC 键时将被单击的按钮。将MessageDialogdefaultCommandIndex属性设置为 0,表示您的第一个按钮 Continue 按钮将是默认按钮。同样,使用cancelCommandIndex 表示另一个按钮将是取消按钮。最后,调用MessageDialog对象的showAsync函数向用户显示对话框,并要求用户在继续使用应用之前采取一些行动。

运行应用并单击“显示消息”按钮。应用的内容将变暗,对话框将显示,如图图 6-14 所示。当点击继续或取消按钮时,将显示您选择的结果,如图图 6-15 。

图 6-14 。向用户显示消息对话框的页面

图 6-15 。消息对话框的结果

弹出窗口

介于工具提示和消息对话框之间,WinJS 提供了一个Flyout控件,用于向用户显示上下文内容和其他控件。这些内容出现在应用主页上方的浮动框中,在视觉上类似于工具提示;然而,当用户的鼠标悬停在某个触发器上时,工具提示会提供描述或指令,而Flyout控件通常会在用户采取更谨慎的动作时显示,比如单击某个东西。例如,您可以使用弹出按钮让您的用户确认他们想要删除一些数据。

与添加消息对话框类似,向应用中添加弹出型按钮包括许多步骤。和AppBar的例子一样,Flyout控件的代码必须直接包含在页面的body元素中,所以在windowscontrols.html中的 app bar 声明之后立即添加来自清单 6-13 的代码。

清单 6-13。 添加弹出型按钮

<div id="myFlyout" data-win-control="WinJS.UI.Flyout">
    <div>This is a flyout.</div>
    <button id="myCloseFlyoutButton">Close flyout</button>
</div>

如果您现在运行应用,它是不可见的,但是您已经创建了一个带有一些文本和一个按钮的Flyout。为了看到Flyout,您需要一些用户可以用来显示它的控件。正如您对MessageDialog所做的那样,您将为此在页面上添加一个按钮。将清单 6-14 中的代码添加到用于显示MessageDialog的按钮之后的windowscontrols.html中。

清单 6-14。 添加按钮以显示弹出型按钮

<button id="myShowFlyoutButton">Show flyout</button>

现在,您将通过将清单 6-15 中高亮显示的代码添加到windowscontrols.jsready函数的末尾来连接按钮。您必须为两个按钮连接事件处理程序——一个显示弹出按钮,一个关闭它。

清单 6-15。 连接按钮点击的事件处理器

ready: function (element, options) {
    // SNIPPED

    // flyout event binding
    document.getElementById("myShowFlyoutButton")
        .addEventListener("click", myShowFlyoutButton_Click, false);
    document.getElementById("myCloseFlyoutButton")
        .addEventListener("click", myCloseFlyoutButton_Click, false);
},

最后一步是定义您在清单 6-15 中连接的两个事件处理程序。清单 6-16 包含了在ready函数中引用的两个函数定义。与清单 6-12 中的事件处理程序一样,注意我已经在PageControl定义之外定义了这些函数。将清单 6-16 中的代码添加到windowscontrols.js中的MessageDialog部分的myShowDialogButton_Click函数定义之后。

清单 6-16。 在 PageControl 定义后添加事件处理程序

function myShowFlyoutButton_Click() {
    myFlyout.winControl.show(myShowFlyoutButton, "top");
}

function myCloseFlyoutButton_Click() {
    myFlyout.winControl.hide();
}

现在您已经准备好了所有的代码,运行您的应用并单击“显示弹出”按钮。因为您在调用show函数时指定了top作为placement参数的值,所以您在清单 6-13 中创建的弹出按钮显示在myShowFlyoutButton上方(参见图 6-16 )。其他有效选项有"bottom""left""right"

图 6-16 。您的弹出按钮可见

任何时候弹出按钮可见,用户都可以通过按 ESC 键或点击关闭它来消除它,这种交互被称为光消除。此外,单击弹出按钮可以隐藏它。使用您可能添加的任何其他控件(如ToggleSwitchRating控件)引起的更改应该会立即生效,但不会隐藏Flyout控件。

设置弹出按钮

SettingsFlyout控件用于给你的应用添加一个小窗口,包含应用某些方面的设置。您的应用可以有几个SettingsFlyout控件,为了与其他 Windows 应用保持一致,每个控件都应该在设置窗格中列出。图 6-17 显示了 Bing 财务应用 ,其“关于设置”弹出按钮打开。

图 6-17 。设置弹出按钮已打开

默认情况下,“设置”面板是隐藏的,直到用户激活它。激活后,设置窗格会列出用户可用的每个SettingsFlyout。用户可以通过以下任何一种方法激活设置窗格 :

  • 将鼠标移动到屏幕的右上角,然后单击“设置”按钮,打开 Windows charms 栏。
  • 通过从触摸屏的右侧向内滑动,然后点击设置按钮来打开 Windows charms 栏;
  • 在键盘上按下 Windows 徽标键+I。

设置面板,甚至是一个特定的SettingsFlyout,也可以通过编程激活,例如,通过点击应用中提供的一个按钮。您将向您的应用添加一个打开设置面板的按钮,然后您可以选择要打开的SettingsFlyout。将清单 6-17 中的代码添加到windowscontrols.html中。

清单 6-17。 添加按钮显示设置弹出按钮

<button id="myShowSettingsButton">Show Settings</button>

定义SettingsFlyout不同于我到目前为止讨论过的任何其他控件。这是因为它是在自己的 HTML 文件中定义的。在 Visual Studio 的解决方案资源管理器中,向pages文件夹添加一个名为settingsflyout的新文件夹。右键单击这个新文件夹,并选择添加新项目的选项。Visual Studio 的添加新项对话框打开(参见图 6-18 )。这次没有选择页面控件项,而是选择 HTML 页面项,并将页面命名为settingsflyout.html

图 6-18 。添加 HTML 页面

然后打开settingsflyout.html文件,用清单 6-18 中的代码替换它的内容。

清单 6-18。 设置弹出页面

<!DOCTYPE html>
<html>
<head>
    <title>Settings Flyout Sample</title>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
</head>
<body>
    <div id="settingsDiv" data-win-control="WinJS.UI.SettingsFlyout"
        aria-label="Settings flyout sample"
        data-win-options="{settingsCommandId:'settingsflyout',width:'wide'}">

        <div class="win-ui-dark win-header" style="background-color: #464646">
            <button type="button" class="win-backbutton"
                onclick="WinJS.UI.SettingsFlyout.show()"></button>
            <div class="win-label">Settings Flyout Sample</div>
        </div>
        <div class="win-content">
            Put your settings here.
        </div>
    </div>
</body>
</html>

注意第一个div元素,它的idsettingsDiv。您已经使用data-win-control属性指出它是一个 WinJS SettingsFlyout控件。您还设置了settingsCommandId属性 ,稍后在将“设置”弹出按钮添加到“设置”窗格时会用到该属性。您还将width属性设置为wide,而不是默认的narrow。在SettingsFlyout控件中,有一个div元素用于您的标题,另一个包含您希望看到的实际内容。

现在您已经创建了将用于您的SettingsFlyout的页面,您必须连接一些事件。将清单 6-19 中高亮显示的代码添加到windowscontrols.jsready函数的末尾。

清单 6-19。 为按钮点击连线事件处理程序

ready: function (element, options) {
    // SNIPPED

    // show the Settings pane when our button is clicked
    document.getElementById("myShowSettingsButton").addEventListener("click", function () {
        WinJS.UI.SettingsFlyout.show();
    }, false);
},

这段代码是按钮的事件处理程序代码,它显示了调用WinJS.UI.SettingsFlyout.show的设置面板。如果你想直接跳到你的SettingsFlyout而不是显示设置面板,你可以使用WinJS.UI.SettingsFlyout.showSettings方法 。

最后一步是让您的应用让 Windows 知道您想要在设置窗格中显示什么设置。清单 6-20 中突出显示的代码应该添加到位于js文件夹中的default.js文件中的processAll调用之前。这段代码定义了一个与SettingsFlyout控件相关联的命令,并将其添加到设置窗格中。将该命令命名为settingsflyout,,以匹配您在settingsflyout.html中设置的settingsCommandId属性。title属性决定该命令在设置窗格中显示的文本。

清单 6-20。 连接事件处理程序来填充设置命令列表

app.addEventListener("activated", function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {

        // SNIPPED

        // add our SettingsFlyout to the list when the Settings pane is shown
        WinJS.Application.onsettings = function (e) {
            e.detail.applicationcommands = {
                "settingsflyout": {
                    title: "Settings Flyout Sample",
                    href: "/pages/settingsflyout/settingsflyout.html"
                }
            };
            WinJS.UI.SettingsFlyout.populateSettings(e);
        };

        args.setPromise(WinJS.UI.processAll().then(function () {
            // SNIPPED
        }));
    }
});

注意default.js中添加这段代码允许设置弹出按钮在你的应用加载到default.html的任何PageControl中可用。通过将该代码移动到每个PageControl的就绪功能,可以从应用的每个页面获得不同的设置。但是,微软的指导建议在整个应用中显示相同的设置列表,禁用任何在特定情况下不适用的设置。

现在,如果你运行你的应用并通过点击显示设置按钮(或任何其他方法)打开设置面板,你现在有一个按钮来打开你的SettingsFlyout,,如图 6-19 中的所示。

图 6-19 。应用的设置面板

点击此按钮打开你的宽格式SettingsFlyout,,如图 6-20 所示。

图 6-20 。“设置”弹出按钮

SettingsFlyout中所做的任何设置更改都会立即生效,用户不必点击保存按钮。当用户完成设置弹出按钮时,无论是否进行了任何更改,他或她都可以单击 Back 按钮返回到设置窗格,或者通过单击SettingsFlyout之外的某个地方将其关闭。

结论

在本章中,您了解了 Windows Library for JavaScript 或 WinJS 提供的许多常见控件。这些控件超越了 HTML 提供的基本控件,允许您以符合 Windows 8 全新现代界面的外观和行为的方式与用户进行交互。在第七章的中,我将讨论为处理项目集合而构建的 WinJS 控件:ListViewFlipViewSemanticZoom

七、WinJS 集合控件

在前两章中,我介绍了一些可以用来构建 Windows 应用商店应用的控件。除了DropDownList控件之外,到目前为止我介绍的所有控件都是为处理单个值而设计的。每个文本输入控件都与单个字符串相关联;每个按钮控件都与一个操作相关联;每个工具提示显示一个项目的描述或说明。事实上,尽管DropDownList控件包含许多可供选择的项目,但它在逻辑上与单个设置相关的选项相关联。

在这一章中,我将介绍 WinJS 提供的基于集合的控件。当您有想要使用模板显示的项目列表时,可以使用这些控件。如果你用过 Windows 8,那么最明显的例子就是 Windows 开始屏幕,如图 7-1 所示。这个开始屏幕显示了我已经安装的应用列表。每一个,都有一个标题;小的或大的平铺图像;以及可选地,显示在标题上的一些实况内容。如你所见,我现在正处于热浪之中。

图 7-1 。Windows 8 开始屏幕

虽然在本章中我不打算演示如何复制 Windows 开始屏幕,但是您将看到如何通过将集合控件绑定到数据列表来构建类似的功能。但是在绑定到数据列表之前,您首先需要理解拥有数据列表意味着什么。

收集

如果您从事编程已经有一段时间了,那么您无疑已经熟悉了项目集合。数组是一种常见的集合类型,数据库查询的结果、驱动器上的文件列表或您喜爱的博客的 RSS 提要中的项目也是如此。WinJS 提供了WinJS.UI.IListDataSource接口,用于在 Windows 应用商店应用中处理这些类型的收藏。此接口可用于向集合中添加新项,编辑或移除集合中的现有项,或将集合绑定到控件以在应用中显示。你将在本章中看到的 WinJS 集合控件、ListViewFlipView,都常用于显示来自IListDataSource的数据。

在某些情况下,您必须创建自己的实现IListDataSource的 JavaScript 类,比如当您想要将ListView控件直接绑定到 web 服务调用的结果时。然而,在许多情况下,您可以利用WinJS.Binding.List类从一组数据中创建一个IListDataSource。这就是我将在本章中解释的。事实上,在大多数情况下,我推荐这种方法,即使是在处理来自 web 服务的数据时。将 web 服务数据加载到一个数组中,然后将它们包装在一个List对象中,这样可以很好地将用户界面与底层数据源分离开来,并为您提供更多的灵活性和控制。我将在第十一章更详细地讨论数据绑定。现在,我将保持它非常简单,因为本章的主要焦点是用来显示这些数据的控件。

让我们从第五章和第六章开始,对你的 WinJSControlsSample 项目做一些修改,这将允许你在本章后面使用ListViewFlipView控件。

项目设置

本章中你将看到的所有例子都将使用相同的项目集合。在这种情况下,它是一组动物。每个动物的定义都有动物的名称、科学分类以及大小不同的图片。让我们将这些数据添加到您的项目中。

  1. 打开 WinJSControlsSample 项目。

  2. Right-click on the js folder in the Solution Explorer and add a new item (see Figure 7-2).

    图 7-2 。向 js 文件夹添加新项目

  3. Select the JavaScript File item (see Figure 7-3).

    图 7-3 。创建 JavaScript 文件

  4. 将文件命名为data.js,然后单击 Add 按钮。

  5. 将清单 7-1 中的代码输入到您的新data.js文件中,并保存该文件。

清单 7-1。 添加数据

var animals = new WinJS.Binding.List([
    {
        name: "Ant",
        classification: "Formicidae",
        pic_sm: "/img/60/Ant.png",
        pic_lg: "/img/400/Ant.png"
    },
    {
        name: "Bat",
        classification: "Chiroptera",
        pic_sm: "/img/60/Bat.png",
        pic_lg: "/img/400/Bat.png"
    },
    {
        name: "Bee",
        classification: "Anthophila",
        pic_sm: "/img/60/Bee.png",
        pic_lg: "/img/400/Bee.png"
    },

    // SNIPPED

    {
        name: "Squirrel",
        classification: "Sciuridae",
        pic_sm: "/img/60/Squirrel.png",
        pic_lg: "/img/400/Squirrel.png"
    },
    {
        name: "Turtle",
        classification: "Chelonii",
        pic_sm: "/img/60/Turtle.png",
        pic_lg: "/img/400/Turtle.png"
    }
]);

这段代码创建了一个由五只动物组成的数组,每只动物都有一个nameclassificationpic_smpic_lg属性。然后,这个数组被包装在一个名为animalsWinJS.Binding.List对象中,这个对象将作为本章其余例子的数据源。

您还必须将每种动物引用的图像添加到项目中的适当目录中:一个 60×60 大小的小图像和一个 400×400 大小的大图像。创建图像的教程超出了本书的范围;但是,您可以使用您喜欢的任何方法。也就是说,Syncfusion 已经创建了 Metro Studio,这是一个包含数百个免费和免版税图标的伟大资源。我用它创作了整本书的许多图标和图像。可以从 Syncfusion 的网站这里下载:http://www.syncfusion/downloads/metrostudio .

本书附带的源代码包括一个名为 WinJSControlsSample 的完整项目,其中包括第 5、6、7、8 章中使用的样本代码。它包括这些示例中使用的所有图像文件,以及 data.js 文件中更长的动物列表。你可以在本书的 press 产品页面(www.apress/9781430257790)的 Source Code/Downloads 选项卡上找到本章的代码示例。

现在您已经有了所需的数据,让我们来看看显示项目集合的不同控件。

控制器

WinJS 提供了两个控件来显示 Windows 应用商店应用中的项目集合:ListView控件和FlipView控件。正如您将看到的,它们在许多方面是相似的,但是它们有一个显著的区别。ListView控件可以一次显示多个项目,用你的项目填满可用空间。另一方面,FlipView控件一次突出显示一个项目,用户可以像翻书一样滚动浏览您的收藏。

WinJS 还提供了几个其他的类,用于ListViewFlipView。两者都支持使用一个WinJS.Binding.Template对象来格式化你的集合中的单个项目。ListView还支持两种布局模式,WinJS.UI.GridLayoutWinJS.UI.ListLayout,这两种模式决定了你的每个项目显示在哪里。最后,您可以使用带有两个ListView控件的WinJS.UI.SemanticZoom类来允许您的用户选择他或她正在查看的数据的分辨率,缩小时是摘要或组级别的信息,放大时是项目级别的信息。您将在下面看一下这些控件和类,从下一节的ListView控件的一些基础开始。

当您学习本章中的示例时,应该将它们添加到前面章节中的 WinJSControlsSample 项目中。对于下面的每一个部分,你都必须按照第五章中添加 htmlcontrols 页面控件的步骤,向项目添加另一个页面控件。确保将所有示例代码放在页面控件的<section aria-label="Main content" role="main"></section>元素之间。您还必须为 home.html 的每个页面控件添加一个导航按钮。最后,每个页面控件都必须引用你在本章前面创建的data.js文件。你可以在本章剩余部分中创建的每个页面控件的head部分添加这个引用(见清单 7-2 )。

清单 7-2。 引用您的动物数据对每个页面进行控制

<head>
    <!-- SNIPPED -->
    <script src="/js/data.js"></script>
</head>

ListView 基础

几乎在每个应用中,你都需要显示一个项目列表,使用ListView控件是最常见的方式。在当前示例中,您将显示清单 7-1 中定义的动物数据列表。首先创建一个名为listViewBasics.html的新页面控件,然后将清单 7-3 中的代码添加到主部分,这将为您的页面添加一个ListView,并将其绑定到您之前在data.js中创建的animals列表。不要忘记引用data.js,如清单 7-2 中的所示。

清单 7-3。 添加列表视图

<div id="listView"
    class="win-selectionstylefilled"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource: animals.dataSource,
        selectionMode: 'none',
        tapBehavior: 'none',
        swipeBehavior: 'none'
    }">
</div>

注意要显示在 HTML 中添加的ListView或任何其他 WinJS 控件,必须在页面的 JavaScript 代码中添加对WinJS.UI.processAll的调用。但是,因为我们的示例使用了页面控件,所以这是在幕后为您处理的。但是,如果您曾经以不同的方式构建页面,请记住这一点。

我还设置了一些其他选项。通过将class属性设置为win-selectionstylefilled,ListView将用纯色背景高亮显示项目。如果没有添加该类,默认情况下将在该项周围绘制一个矩形。此外,我已经将selectionModetapBehavior,swipeBehavior属性设置为none,这实质上是将您的列表置于只读模式,在这种模式下不能选择任何项目,当您单击一个项目时也不会发生任何事情。现在运行应用。你应该会看到类似于图 7-4 的东西。

图 7-4 。一个无用的列表视图

你所有的数据都在那里,但这不是一个非常有用的观点。事实上,这很令人困惑,坦白说,还有点难看。在下一节,我将解释如何使用模板使它更实用。关于selectionModetapBehaviorswipeBehavior和其他ListView属性的文档可在http://msdn.microsoft/en-us/library/windows/apps/br211837.aspx的 MSDN 上获得。我鼓励您在继续之前花几分钟时间探索这些属性的其他值组合。例如,将selectionMode设置为multi并将swipeBehavior设置为select,您可以看到如何开始创建一个界面,其行为类似于 Windows 自带的邮件应用中的电子邮件列表。

模板

你可能在清单 7-1 中注意到,集合中的条目可能比单个值更复杂,比如一个字符串。在当前情况下,每个项目有四个不同的属性:nameclassificationpic_smpic_lg。没有进一步的指示,ListView简单地显示集合中每个项目的文本表示,如图图 7-4 所示。使用模板,您可以指定如何显示项目的每个属性。通过将高亮显示的行添加到您的代码中,修改您添加到listViewBasics.html中的代码以匹配清单 7-4 。

清单 7-4。 给你的 ListView 添加模板

<div id="listViewTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="listViewItem">
        <img src="#" class="listViewItemImage" data-win-bind="src: pic_sm" />
        <div class="listViewItemText">
            <h4 data-win-bind="innerText: name"></h4>
            <h6 data-win-bind="innerText: classification"></h6>
        </div>
    </div>
</div>

<div id="listView"
    class="win-selectionstylefilled"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource: animals.dataSource,
        itemTemplate: select('#listViewTemplate'),
        selectionMode: 'none',
        tapBehavior: 'none',
        swipeBehavior: 'none'
    }">
</div>

这段代码创建了一个Template控件,它定义了数据源中每个项目的属性应该如何显示。您将在整个Template中使用data-win-bind属性来设置绑定,这些绑定将用于将项目的值分配给正确的 HTML 属性。通过给id属性赋值,您就可以设置ListViewitemTemplate属性,以便在显示时使用这个Template。我将在第十一章中更详细地介绍数据绑定。当你运行应用时,你可以看到,如图图 7-5 所示,你离目标越来越近了,但仍有差距。

图 7-5 。您的 ListView 就快完成了

你必须给你的页面控件添加一些 CSS 来润色一下。Visual Studio 在您创建页面控件时添加了一个名为listViewBasics.css的文件。打开文件并添加来自清单 7-5 的 CSS 代码。这段代码设置适当的宽度、高度、边距和其他样式属性,以使页面按预期显示。

清单 7-5。 CSS 为你的基本 ListView 示例

.listViewItem {
    width: 250px;
    height: 75px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .listViewItem img.listViewItemImage {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .listViewItem .listViewItemText {
        margin: 5px;
        -ms-grid-column: 2;
    }

#listView {
    height: 400px;
    width: 100%;
    -ms-grid-column-span: 2;
}

现在已经添加了所有代码,您可以再次运行应用。这一次,您终于看到了您所期望看到的:一个格式良好的网格,包含来自您的animals数据源的数据(参见图 7-6 )。每个项目都显示彩色图标、动物名称及其分类,这在本章前面的data.js中已经定义。

图 7-6 。一个漂亮的列表视图

布局

你可能注意到了在一个ListView控件中项目的默认显示是网格模式。从左上角开始(在从左到右的语言中,如英语),项在一列中从上到下加载。当到达ListView的底部时,从第一列的右侧开始新的一列。如果与 ListView 控件所占用的空间相比,所显示的每个项目的可视大小较小,这通常是首选显示。但是,如果项模板需要更多的空间,或者如果 ListView 显示在狭窄的空间中,例如当您的应用处于对齐模式时,更紧凑的垂直布局可能是首选。这可以通过使用ListViewlayout属性来完成。

添加一个名为listViewLayouts.html的新页面控件并引用data.js。然后将清单 7-6 中的代码添加到主部分。这段代码非常类似于您在前面几节中添加的内容。有一个Template控制和两个ListView控制。两个ListView控件绑定到同一个数据源并引用同一个Template控件。唯一的区别是第一个ListView的布局属性设置为WinJS.UI.GridLayout,而第二个ListView的布局属性设置为WinJS.UI.ListLayout

注意我有意忽略了一些用于布局你的示例应用屏幕的 HTML 和 CSS。我将涵盖与所描述的功能相关的所有代码,但是因为一些支持代码片段没有包含在代码清单中,所以您的应用看起来可能与这里包含的图略有不同。您可以通过引用名为 WinJSControlsSample 的完整项目来查看我使用的所有代码,该项目包含在本书附带的源代码中。你可以在本书的 press 产品页面(www.apress/9781430257790)的 Source Code/Downloads 选项卡上找到本章的代码示例。

清单 7-6。 添加不同布局的 ListView 控件

<div id="listViewTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="listViewItem">
        <img src="#" class="listViewItemImage" data-win-bind="src: pic_sm" />
        <div class="listViewItemText">
            <h4 data-win-bind="innerText: name"></h4>
            <h6 data-win-bind="innerText: classification"></h6>
        </div>
    </div>
</div>

<div id="col1">
    <div id="listViewGridLayout"
        class="win-selectionstylefilled"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{
            itemDataSource: animals.dataSource,
            itemTemplate: select('#listViewTemplate'),
            selectionMode: 'none',
            tapBehavior: 'none',
            swipeBehavior: 'none',
            layout: { type: WinJS.UI.GridLayout }
        }">
    </div>
</div>

<div id="col2">
    <div id="listViewListLayout"
        class="win-selectionstylefilled"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{
            itemDataSource: animals.dataSource,
            itemTemplate: select('#listViewTemplate'),
            selectionMode: 'none',
            tapBehavior: 'none',
            swipeBehavior: 'none',
            layout: { type: WinJS.UI.ListLayout }
        }">
    </div>
</div>

接下来,将清单 7-7 中的代码从添加到到listViewLayouts.css,然后运行应用。您应该会看到两个ListView 控件,如图 7-7 中的所示。除了更窄以允许两个ListView控件适合屏幕之外,第一个控件与上一节的ListView相同。第二个ListView在垂直列表中显示它的项目。每个单独的项目在两个控件中显示相同,说明一个Template可以在许多控件中重用,并且多个控件可以绑定到同一个数据源。

清单 7-7。 CSS 为您的列表视图布局示例

.listViewItem {
    width: 250px;
    height: 75px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .listViewItem img.listViewItemImage {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .listViewItem .listViewItemText {
        margin: 5px;
        -ms-grid-column: 2;
    }

#listViewGridLayout {
    height: 400px;
    width: calc(100% - 50px);
    border: 1px solid #464646; /* make it easier to distinguish  */
}

#listViewListLayout {
    height: 400px;
    width: 300px;
    border: 1px solid #464646; /* make it easier to distinguish  */
}

图 7-7 。使用不同布局的两个 ListView 控件

WinJS 只包括这两个布局选项:GridLayoutListLayout。如果您需要一个不同的布局,比如一个以行而不是列来定位数据的网格布局,您可以通过实现WinJS.UI.ILayout接口来选择自己实现一个新的布局选项。这超出了本书的范围,但是关于这个接口的更多信息可以在 MSDN 的http://msdn.microsoft/en-us/library/windows/apps/jj712247.aspx上找到。

分组和语义缩放

通常,长长的项目列表非常有意义。但是,有时,尤其是当列表很长时,可以通过对数据进行分组来改善用户体验。例如,一个城市列表可以按国家分组,一个电子邮件列表可以按发件人的电子邮件地址分组,或者,正如您在我们的示例中所做的,一个动物列表可以按字母顺序分组。

添加一个名为listViewGrouping.html的新页面控件并引用data.js。然后将清单 7-8 中的代码添加到主部分。这段代码类似于我们的第一个ListView示例,除了在这个示例中,我添加了另一个Template控件,用于每个组的标题。我还在ListView控件上设置了一些属性,以指示哪些文本应该显示在组标题中,以及标题应该使用我们新的Template

清单 7-8。 添加带有分组的 ListView】

<div id="listViewHeaderTemplate"
    data-win-control="WinJS.Binding.Template"
    style="display: none">
    <div class="listViewHeader">
        <h1 data-win-bind="innerText: name"></h1>
    </div>
</div>

<div id="listViewTemplate"
    data-win-control="WinJS.Binding.Template"
    style="display: none">
    <div class="listViewItem">
        <img src="#" class="listViewItemImage" data-win-bind="src: pic_sm" />
        <div class="listViewItemText">
            <h4 data-win-bind="innerText: name"></h4>
            <h6 data-win-bind="innerText: classification"></h6>
        </div>
    </div>
</div>

<div id="listView"
    class="win-selectionstylefilled"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{
        itemDataSource: groupedAnimals.dataSource,
        itemTemplate: select('#listViewTemplate'),
        groupDataSource: groupedAnimals.groups.dataSource,
        groupHeaderTemplate: select('#listViewHeaderTemplate'),
        selectionMode: 'none',
        tapBehavior: 'none',
        swipeBehavior: 'none'
    }">
</div>

在清单 7-8 中,我将ListViewitemDataSource属性设置为groupedAnimals.dataSource,将ListViewgroupDataSource属性设置为groupedAnimals.groups.dataSource,但是groupedAnimals还不存在。您可以通过将清单 7-9 中的代码添加到之前创建的data.js JavaScript 文件的末尾来定义它。这段代码定义了一个用于对组进行排序的函数(compareGroups)、一个指示集合中的哪些项目应该分组在一起的函数(getGroupKey)以及一个指示应该使用哪些数据来填充在groupHeaderTemplate属性中指定的Template的函数(getGroupData)。然后代码使用这三个函数基于您的animals集合创建一个新的WinJS.Binding.List。有关创建分组列表的更多信息,请访问 MSDN 的http://msdn.microsoft/en-us/library/windows/apps/hh700742.aspx .

清单 7-9。 将你的数据分组

function compareGroups(left, right) {
    return left.toUpperCase().charCodeAt(0) - right.toUpperCase().charCodeAt(0);
}

function getGroupKey(dataItem) {
    return dataItem.name.toUpperCase().charAt(0);
}

function getGroupData(dataItem) {
    return {
        name: dataItem.name.toUpperCase().charAt(0)
    };
}

var groupedAnimals = animals.createGrouped(getGroupKey, getGroupData, compareGroups);

在这个例子中,我使用了动物名称的第一个字母作为分组关键字和分组标题。在一个更复杂的例子中,您可以按国家对城市进行分组,getGroupKey函数可以返回该国家的 ISO 国家代码。同样,因为在groupHeaderTemplate属性中指定的模板不限于简单的文本,所以getGroupData可以返回一个带有国家名称、其大洲和国旗图像的对象。在这种情况下,您还可以修改compareGroups函数,按照国家名称、洲、甚至国家的面积(平方英里)进行排序。

现在剩下的工作就是样式化这个ListView,所以让我们通过添加清单 7-10 中的代码到用页面控件创建的listViewGroupings文件中。同样,这类似于在清单 7-5 中添加的 CSS 代码,除了这个代码包含了你的组标题的样式。运行应用,查看类似于图 7-8 中的分组ListView

清单 7-10。 用于列表视图分组的样式

.listViewHeader
{
    width: 50px;
    height: 50px;
    padding: 8px;
}

.listViewItem {
    width: 250px;
    height: 75px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .listViewItem img.listViewItemImage {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .listViewItem .listViewItemText {
        margin: 5px;
        -ms-grid-column: 2;
    }

#listView {
    height: 400px;
    width: 100%;
    -ms-grid-column-span: 2;
}

图 7-8 。项目按字母顺序分组的列表视图

还不错,但是想象一下一个包含数百种动物数据的ListView。这将是很好的能够看到你的动物群体作为一个索引列表,然后能够使用该索引找到你正在寻找的动物。WinJS 为此提供了SemanticZoom控件。如果你不熟悉语义变焦的概念以及它与光学变焦的区别,我将尝试描述它们。光学缩放是以不同的放大级别查看同一项目,而语义缩放允许您查看每个项目的少量数据,以换取查看更多项目的数据。我们来看几个类比。

光学变焦 是照片编辑软件的常用功能。你可以放大照片中的一片草,也可以缩小来看整片草坪。在这两种情况下,你看到的是同一张照片,只是放大倍数不同。另一方面,语义缩放是在线绘图软件的常见功能。你可以放大看到你居住的街道,但当你缩小时,你的街道消失了,你看到的是城市。继续缩小,你会看到州,然后是国家,然后是大陆。与照片中草叶的细节仍然是照片的一部分不同,缩小地图会导致街道的细节被其他东西的细节所取代。

语义缩放的另一个常见案例是日历。在最底层,您可以看到您在某一天参加的所有会议,包括时间、地点和其他与会者的详细信息。缩小时,您可能会看到整个星期,只列出会议标题和时间。进一步缩小,你可能看不到任何关于你的会议的信息,而只能看到年份和月份。

注意SemanticZoom控件只支持一个缩放级别。如果你的应用有一个更深的层次,我鼓励你遵循第四章中介绍的网格应用项目模板,为层次的每一层导航到一个新的页面。

SemanticZoom控件允许您指定数据的不同视图,包含不同数量的细节。如果你的列表中有数百种动物,缩小到只看到组标题会很有帮助。然后你可以选择一个直接跳到你的动物列表的那一部分。您可以通过几个额外的步骤来添加这些功能。首先,将清单 7-11 中突出显示的代码从添加到listViewGrouping.html。我已经添加了另一个Template控件和ListView控件,它们将在你缩小时使用。我还添加了SemanticZoom控件,它首先包含用户放大到最大细节级别时看到的ListView,其次包含用户缩小以查看更多项目的更少细节时看到的ListView。请注意,这些控件的顺序很重要,更详细的放大视图必须放在不太详细的缩小视图之前。

清单 7-11。 添加语义缩放及相关控件

<div id="listViewHeaderTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="listViewHeader">
        <h1 data-win-bind="innerText: name"></h1>
    </div>
</div>

<div id="listViewTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="listViewItem">
        <img src="#" class="listViewItemImage" data-win-bind="src: pic_sm" />
        <div class="listViewItemText">
            <h4 data-win-bind="innerText: name"></h4>
            <h6 data-win-bind="innerText: classification"></h6>
        </div>
    </div>
</div>

<div id="semanticZoomTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="semanticZoomItem">
        <h2 class="semanticZoomItemText" data-win-bind="innerText: name"></h2>
    </div>
</div>

<div id="semanticZoom" data-win-control="WinJS.UI.SemanticZoom">

    <!-- zoomed in view -->
    <div id="listView"
        class="win-selectionstylefilled"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{
            itemDataSource: groupedAnimals.dataSource,
            itemTemplate: select('#listViewTemplate'),
            groupDataSource: groupedAnimals.groups.dataSource,
            groupHeaderTemplate: select('#listViewHeaderTemplate'),
            selectionMode: 'none',
            tapBehavior: 'none',
            swipeBehavior: 'none'
    }">
    </div>

    <!-- zoomed out view -->
    <div id="zoomedOutListView"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{
            itemDataSource: groupedAnimals.groups.dataSource,
            itemTemplate: select('#semanticZoomTemplate'),
            selectionMode: 'none',
            tapBehavior: 'invoke',
            swipeBehavior: 'none'
    }">
    </div>

</div>

你可以停在那里,有一个工作的例子,但稍加设计,你可以有一个工作的例子,也很好看。将清单 7-12 中的代码添加到listViewGrouping.css中,并运行应用。

清单 7-12。 语义缩放的附加样式

#zoomedOutListView {
    height: 400px;
    width: 100%;
    -ms-grid-column-span: 2;
}

#semanticZoom {
    height: 400px;
    width: 100%;
    -ms-grid-column-span: 2;
}

.semanticZoomItem
{
    color: #ffffff;
    background-color: #464646;
    width: 150px;
    height: 40px;
    padding: 5px 15px;
}

起初,ListView看起来和你添加分组时差不多,显示了所有动物的详细列表(见图 7-9 )。然而,您会注意到的一个不同之处是在ListView的右下角增加了一个小减号(“-”)按钮。该按钮是激活SemanticZoom和缩小的几种方式之一。

图 7-9 。添加了 SemanticZoom 的 ListView

要缩小并查看图 7-10 ,用户可以

  • 单击减号按钮。
  • 按住键盘上的 Ctrl 键,并使用鼠标上的滚轮向下滚动。
  • 使用第一章中描述的捏手势。当然,这只适用于触摸屏。

图 7-10 。缩小的列表视图

ListView中确定所需位置后,用户可以执行以下操作之一进行放大:

  • 通过单击或直接点击来选择群组。
  • 将鼠标悬停在所需的组上,然后按住 Ctrl 键并在鼠标滚轮上向上滚动。
  • 使用第一章中描述的拉伸手势。同样,这需要触摸屏。

注意开箱即用,唯一能与SemanticZoom控件一起工作的 WinJS 控件是ListView。然而,通过实现WinJS.UI.IZoomableView接口,可以创建你自己的控件,或者修改另一个控件。关于此界面的更多信息,请访问MSDN at http://msdn.microsoft/en-us/library/windows/apps/br229794.aspx

FlipView

到目前为止,您已经看到了许多查看项目列表的技术,但是每种技术都一次向用户显示几个项目。虽然这是一个非常常见的场景,但有时,您希望将列表中的项目一次一个地呈现给用户,WinJS 为此任务提供了FlipView控件。FlipView控件的一个常见例子是一个相册,用户可以看到一张照片和一个标题,然后点击一个按钮前进到下一张。因此,让我们建立一个这样的例子。

添加一个名为flipView.html的新页面控件并引用data.js。然后将清单 7-13 中的代码添加到主部分。你会再次注意到这段代码与之前的ListView例子非常相似。事实上,如果您将data-win-control属性从WinJS.UI.FlipView更改为WinJS.UI.ListView,您仍然可以使用应用。这是因为FlipViewListView都绑定到相同类型的数据源,并且都用相同类型的模板显示它们的项目。

清单 7-13。 添加一个动画视图

<div id="flipViewTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
    <div class="imageWithOverlay">
        <img class="image" data-win-bind="src: pic_lg; alt: name" />
        <div class="overlay">
            <h2 class="title" data-win-bind="innerText: name"></h2>
        </div>
    </div>
</div>
<div id="flipView"
    data-win-control="WinJS.UI.FlipView"
    data-win-options="{
        itemDataSource: animals.dataSource,
        itemTemplate: select('#flipViewTemplate')
    }">
</div>

让我们通过添加来自清单 7-14 到flipView.css的 CSS 代码来设置FlipView的样式。在这个例子中有相当多的 CSS 代码,但这主要是因为我希望图像标题显示在覆盖在图像底部的半透明块中。你可以在图 7-11 中看到结果。用户可以通过点击箭头或在触摸屏上滑动来从一幅图像滚动到下一幅图像。

清单 7-14。 设计您的动画视图

#flipView
{
    width: 400px;
    height: 400px;
    border: solid 1px black;
}

.flipViewContent
{
    width: 400px;
    height: 400px;
}

.imageWithOverlay
{
    display: -ms-grid;
    -ms-grid-columns: 1fr;
    -ms-grid-rows: 1fr;
    width: 400px;
    height: 400px;
}

    .imageWithOverlay img
    {
        width: 100%;
        height: 100%;
    }

    .imageWithOverlay .overlay
    {
        position: relative;
        -ms-grid-row-align: end;
        background-color: rgba(0,0,0,0.65);
        height: 40px;
        padding: 20px 15px;
        overflow: hidden;
    }

        .imageWithOverlay .overlay .title
        {
            color: rgba(255, 255, 255, 0.8);
        }

图 7-11 。你的动物的全景

一个常见的改进是在你的FlipView,下面的ListView中提供图像的缩略图,两个控件绑定到同一个数据源。然而,FlipView并不局限于显示带标题的图片。例如,如果您正在构建一个定制的文档阅读应用,您可以使用一个FlipView来显示文档的每一页。

结论

在本章中,您看到了几种不同的向用户显示项目集合的技术。这里介绍的控件——ListView及其布局选项,TemplateSemanticZoom,FlipView—无疑会在你的 Windows 应用商店中找到它们的位置。虽然我只触及了这些控件的表面,但是它们提供了丰富的功能,并且有许多定制。我将在后面的章节中探讨其中的一些功能。

本文标签: 入门商店指南Windows