《101 Windows Phone 7 Apps》读书笔记-Weight Tracker

课程内容

Ø Charts & Graphs

 

    你平时关注自己的体重吗?Weight Tracker使得你可以随时跟踪自己的体重,并且提供几种体重发展趋势的视图。它是一个基于Pivot控件的、具有三条Pivot Item的应用:

➔列表-测量体重的原始数据列表,支持数据的添加和删除。连续数据记录所体现的体重增减趋势通过上升/下降箭头来表示。

➔图-在一个折线图上绘制我们体重随时间变化的曲线,同时,可以显示我们在应用程序的设置页面中定义的目标体重。我们可以浏览所有的数据,或者根据自身的需求缩小浏览范围。

➔进度-根据最终的瘦身计划,总结我们的减肥进度。这个仪表盘视图通过饼图来实现。

    虽然这是一个基于Pivot控件的应用程序,但是本章内容的目的是演示如何在我们的应用程序中加入图和表。

 

Charts & Graphs

    Silverlight Team已经创建了一系列开源的图表控件,包括柱状图、折线图、饼图和气泡图等等。这些控件是早些年为桌面的Silverlight版本所创建的,它们在Silverlight Toolkit中发布。笔者撰稿时,这些控件并没有包含在Silverlight for Windows Phone Toolkit中,所以我们必须单独去下载。但是,下载这些控件的源代码的地方很难找。

    目前,获取这些控件最好的途径就是直接上David Anson的博客去下载。David是微软的一名员工,他负责这些控件的开发。另外,他也非常热心地浏览了本章的内容。他提供了这些控件的“development releases”版本,目的是为了在微软正式发布工具包之前,展示它们最新的功能,解决最近的问题。他提供的发布中,包含了源代码和编译后的DLL文件。该源代码经编译后,可以在桌面Silverlight 的扩展版本-Windows Phone平台上使用,同时也可以在Windows Presentation Foundation (WPF)中使用。我们可以在http://bit.ly/datavis4中获取本书中使用的“Data Visualization Development Release 4”。

    如果我们不想使用这个非官方的版本,也可以从Silverlight Toolkit(为桌面计算机所写的版本)中下载图表控件。但问题是我们不能使用最新的Silverlight Toolkit版本,我们只能下载手机平台通用的Silverlight Toolkit版本(在2009年11月份时为Silverlight 3发布的版本),可以在http://bit.ly/sl3toolkit这里下载到。与David发布的版本相比,使用这个版本的缺点就是,它的性能没有得到提高,而且也不支持stacked series。

    无论我们是从哪里得到的控件,都必须添加对System.Windows.Controls. DataVisualization.Toolkit.dll的引用,该二进制集包含了所有图表相关的功能。在David发布的版本中,使用压缩文件中Binaries\Silverlight3目录下的文件。如果我们安装的是2009年11月份的Silverlight Toolkit,那么我们可以在%ProgramFiles%\Microsoft SDKs\ Silverlight\v3.0\Toolkit\Nov09\Bin路径下找到该文件。

    在笔者撰稿时,Silverlight 4 Toolkit中的图表控件无法运行在Windows Phone平台上!

    虽然最新的Silverlight Toolkit包含了本章介绍的图表控件,但是我们目前还不能使用。虽然在Silverlight 4版本中引入了一些新的功能,但是Windows Phone OS 7.0 中集成的Silverlight 版本是基于Silverlight 3的自定义版本。所以,大多数的Silverlight 2 或者Silverlight 3的代码可以运行在Windows Phone平台上,但是Silverlight 4的代码就不可以。Silverlight 4中的图表控件需要的功能不被Windows Phone版本的Silverlight所支持,所以尝试使用该版本会导致运行时抛出很难解析的异常。这些Silverlight桌面版本和Windows Phone平台版本之间的差别希望在将来会逐渐消失。

   为了使得图表控件正常工作,我们必须添加对Silverlight 3桌面版本的二进制集的引用!

    如果我们不添加对Silverlight 3桌面版本的二进制集System.Windows.Controls.dll的引用,在尝试使用这些图表控件时,会得到一个神秘的异常。确保我们添加了正确的引用,一般典型的安装目录位于“%ProgramFiles%\Microsoft SDKs\Silverlight\v3.0\ Libraries\Client”。

 

Regular Series

   “System.Windows.Controls.DataVisualization.Charting”命名空间中图表的主要元素是Chart。为了得到不同类型的图表,我们可以在Chart元素中放置不同类型的图表。目前,图表的类型有15种:7种常用图表、8种stacked图表。所有常用的图表如表29.1所示。

imageimageimageimageimageimageimage

表29.1 七种Nonstacked图表类型的默认Light-Theme渲染效果,所有的图表具有相同的三个数据点。

    每种图表显示的是light主题下的默认渲染效果,看上去很中规中矩(尽管使用了手机显示不友好的渐变效果)。但是,这种默认渲染效果在dark主题下就显得不是很恰当,因为说明文字变成了白色,而框的背景色仍旧是light主题下的渐变效果。每种图表可以使用简单的{Binding}语法将它的ItemsSource绑定到该数组,然后为其横轴确定每个X属性,为其纵轴确定每个Y属性。我们也可以不使用数据绑定,直接操作一个图表,但是这样通过背后代码的方式显得有些笨拙,因为这样做的话,我们就不能通过名称来访问图表了。单个图表中,可以包含多个重叠的类型。可以为每个区域赋值不同的数据,产生如图29.1所示的效果(light主题下)。

image

图29.1 在同一图表中使用两种类型来填充。

    每种类型的图表,其种类可以不同。虽然这的确有点奇怪,图29.2将所有7种类型的图表整合到了一起。

image

图29.2 在同一张图表中整合了七种类型的nonstacked图表。

 

Stacked Series

    在图表控件的第四个发布版本中,表29.1中的前面4种类型具有两个stacked版本:一个用来存放绝对值,另一个用来存放相对值,这些相对值相加的总和为100%。表29.2展示了这八个stacked版本的图表。就像图29.1一样,它们支持多个子图表的显示,正如它们名称所暗示的,每个子图只是显示内容,而非相互重叠。

imageimageimageimageimageimageimageimage

表29.2中的每个图表中使用相同的数据内容

    Stacked系列的图表包含了一些对图表的定义。有了以上的数据内容,表29.2中的XAML片段可以将三种类型的定义绑定到每个Point[]元素。在绑定到一个包含点的数组以后,IndependentValuePath和DependentValuePath的分配和之前图表的分配方式一样。表29.2在 Light主题下八种Stacked类型图表的默认渲染效果,其数据集相同。

    正如你所看到的,获得漂亮的图表渲染其实并不难。图表可以对其横轴和纵轴进行合理的缩放,甚至在有需要时可以将其轴的标签错开(如图29.1所示)。它可以自动把不同的颜色应用到数据当中,还有其他的一些功能这里没有显示。图表,以及它不同种类的对象,也具有大量的属性用来格式化其内容、标注、标题、轴和数据点等等。虽然思考我们想要的图表的样式比较费力(甚至是简单到隐藏标注或者改变数据的颜色),但是对其进行自定义的类型是很多的。在下一节中,Weight Tracker展示了如何对折线图和饼图做一些自定义的工作。

    第四个发布版本包含了5个Non-stacked类型图表的第二种实现方法(LineSeries, AreaSeries, BarSeries, ColumnSeries, and ScatterSeries)。这个新的集合位于“System.Windows.Controls.DataVisualization.Charting.Compatible”命名空间下。它们的API几乎和本书所介绍的版本一致,但是在其内部,它们使用了新的架构来实现stacked类型的对象。因此,它们包含了一些性能上的提升,甚至在一些当前版本图表无法使用的地方,它们就可以胜任。虽然我们可能无法体会到性能上的提升,除非我们对图表中的数据进行连续快速的刷新,但是我们应该考虑使用这些新的图表。

 

The Main Page

    Weight Tracker具有一个主页面、一个设置页面、一个帮助页面和一个关于页面(后面两个页面并没有什么太大的亮点,因此这里不做介绍)。除了应用程序栏和状态栏,主页面包含了三个Item的Pivot页面。这三个Item在本章的开始部分已经进行了介绍,如图29.3所示。

imageimageimage

图29.3 三个Pivot Item:列表、图和进度。

 

The User Interface

➔Chart及其类型元素的命名空间包含了一个charting前缀。Chartingprimitives这个前缀被使用在Chart默认风格的列表拷贝中。Datavis前缀用于ResourceDictionaryCollection类型,列表中饼图的自定义需要用到它。

➔该页面中三个图表用到的自定义风格(ChartStyle)是Chart控件默认风格的拷贝,但也对其做了一些修改,例如,删除了标题和文字注释,减小了页边距和填充,减少了边框。

   我们可以找到Chart默认的风格和所有相关的类型,它们位于Silverlight Toolkit的generic.xaml文件中。源代码位于“%ProgramFiles%\Microsoft SDKs\Silverlight\v3.0\Toolkit \Nov09\Source”目录下的“Source code.zip”文件中。在该文件中,相关的XAML文件可以在“Controls.DataVisualization.Toolkit\Themes”中找到。这里面也包含了描述每种样式的独立的XAML文件。比如,Chart的默认风格也可以在“Controls.DataVisualization.Toolkit \Charting\Chart\”目录的Chart.xaml文件中找到。

➔因为每个Pivot Item页面上包含了很多信息,所以每页的内容具有-24的上边距,用来占据标题和内容之间的一些空白。在我们做修改的过程中,遇到违背这些设计原则的时候,我们必须非常小心,因为这样的话,与其他的Windows Phone应用程序相比,有可能会使我们写的应用程序看上去很奇怪。

➔第一个Pivot Item中可编辑的体重列表被实现为一个用户控件,名字为WeighInEditableList。该控件包含了一个list box,其值与Collection属性绑定;它还包括了显示在list box上方的三个控件:名字为“Weight”的text box、名字为“Date”的text box和添加按钮。 List box Item也使用了上下文菜单,支持记录的逐条删除。它被打包为用户控件,因为它还被设置页面用来浏览并编辑目标体重的列表。该用户控件的源代码在本章不做介绍,但我们可以在提供的Visual Studio工程文件中找到。

➔ 每条体重由WeighIn类表示,它除了包含三个可读写的属性Weight、Date和Delta以外,还具有一些方便的只读属性,可以被WeighInEditableList中的list box数据模板使用。WeighInEditableList使用的集合是一个自定义的WeighInCollection类,它从ObservableCollection<WeighIn>继承而来。在添加新记录或者删除旧记录时,它自动对记录按照时间的倒序进行排列,计算相应的Delta值(用来显示向上/向下的箭头)。

➔第二个Pivot item包含了两种类型的一张图表:一个用于体重列表,另一个用于目标体重列表。体重列表通过折线图呈现,而目标体重则通过散射图呈现(它看上去和折线图很类似,但是没有连接线)。设置散射图的源代码位于背后的代码中。

➔ 除了将自定义的ChartStyle样式应用到图表以外,其自身以及对应的各种类型也做了一些自定义工作:

    * 图表中加入了背景,使得它与页面的背景相匹配(或者,这个工作也可以在ChartStyle中完成)。

    * 图表给出了显式的X轴,所以我们可以做三个自定义工作:显示垂直网格线,改变日期的显示格式(使得年份不出现),限制X轴显示的值的范围(在背后代码中完成)。

      注意:轴的类型是DateTimeAxis,它具有显示DateTime值的制定功能任何.NET格式的字符串可以用来给StringFormat赋值。

    * 折线表中使用的线段和点的风格已经做了一些更改。例如,线径减小,线段和点的颜色已经与当前主题的颜色相匹配,每个点的渐变填充效果被移除等等。

    * 散射图中每个数据点的风格已经做了更改,使其看上去更像是一个个的星星。这是通过黄色矩形的starimage透明度来实现的。

   注意:改变图表的视觉属性不像设置画刷或者厚度那么简单!相反,我们经常需要使用所有包含这种设置的风格。这对于用户来说,虽然牺牲了简单性,但是发挥了最大限度的灵活性。我们可以从David Anson的博客中下载到一些已经编译好的适用于手机的图表样式,下载地址如下:http://bit.ly/phonechartstyles. 图表集合中,后面几种类型的渲染建立在前面几种类型的基础上,这样做是为了使得目标体重的星标不被折线图所遮盖。

➔第三个(也是最后一个)Pivot Item具有一些text block控件,它们之间嵌入了两个饼图。每个饼图的XAML代码看上去很类似,因为唯一的不同就是在背后代码中设置的需要显示的数据。与折线图、散射图一样,饼图具有整个页面范围的背景,用户可以对各个饼片的填充进行自定义。

    为图表中的数据点选择颜色时,无论是同种类型或者是不同类型,它在分配给Palette属性的样式集合中进行选择。这个集合可以被更改,每种包含了Palette属性的图表类型,也可以具有其自身拥有的集合。Chart的默认样式为Palette属性分配了15种画刷(如表29.1、29.2和图29.1所示,从蓝色、红色以及绿色的渐变开始)。因为该列表中的饼图只包含了两个饼片,而且我们只想要第一个饼片可见,所以这些饼图的Palette使用了两个画刷,第二个画刷用于匹配图的背景。

    为了证实这种影响的效果,图29.4显示了本应用程序的折线图和散射图,不过它们的各种自定义风格已经被移除。第二幅图片展示了从图表中移除Style=”{StaticResource ChartStyle}”的效果。第一幅图片展示了在不进行代码修改的情况下,改变图表至最简单的版本的效果:

imageimageimage

图29.4 通过设置属性来自定义图表,也可以通过更改ChartStyle中的控件模板来自定义图表

    许多合理的自定义只能够通过修改图表控件的源代码来实现,比如,在空间紧张的情况下,禁止轴标签的自动交错显示。幸运的是,由于这些控件都是开源的,所以这是个可行的方案。

 

The Code-Behind

    主页面的cs代码,它利用可观察的集合使得三个Pivot Item页面中的所有数据保持更新。本应用程序管理着两个可观察的集合:一个用于体重列表、另一个用于目标体重列表。它们在Settings.cs文件中给出了定义,同时,该文件还给出了主页面表格中所选择的起始日期的记录设置。

注意:

➔ 虽然页面的数据用于体重列表(第一个Pivot Item中的可编辑列表和第二个Pivot Item中的折线图),但是在OnNavigatedTo事件的最后,这个列表将散射图 Item的数据源覆盖为目标体重列表(DataPointSeries是七个non-stacked类型图表的公共基类)。

➔ 该页面只把当前选择的Pivot Item记录在页面状态中,而不是记录在隔离存储空间里。那是因为大多数用户启动一个新的实例时,他们想要做的第一件事件就是记录一个新的体重。

➔ 在UpdateProgress事件的最后,会给每个饼图一个简单的带有两个数字的数据源。第一个数字代表了体重和已用时间的比值,第二个数字代表了体重和剩余时间的比值。这使得饼图可以为页面中罗列的百分比提供可视化的视图。

➔为了使得两个date picker控件能够对主图表进行过滤,GraphDatePicker_ValueChanged事件设置了图表中X轴能够显示的最小和最大值。

 

The Settings Page

    设置页面如图29.5所示,使得用户可以在主页面上进行浏览、添加、删除实际体重数据的同时,对目标体重的数据也可以进行浏览、添加和删除操作。那是因为它同样使用了WeighInEditableList这个用户控件。该设置页面还包含了一个对实际体重和目标体重进行批量删除的按钮。

    由于大多数的功能是由WeighInEditableList这个用户控件提供的,所以设置页面的实现就非常的简明。如果我们将WeighInEditableList的IsGoalList属性设置为True,可以使得每个体重的附近显示星标,而不是主页面上的那种上升/下降箭头。

image

图29.5 与主页面中使用的控件相同,设置页面提供了对目标体重列表的编辑功能。

 

 

posted on 2012-08-17 07:45  施炯  阅读(1798)  评论(0编辑  收藏  举报