设为首页 收藏本站
查看: 873|回复: 0

《101 Windows Phone 7 Apps》读书笔记-BABY MILESTONES

[复制链接]

尚未签到

发表于 2015-5-9 11:36:34 | 显示全部楼层 |阅读模式
  课程内容
  

Ø图片的读写  Ø序列化
  Ø双向数据绑定
  

      Baby Milestones将婴儿从出生到2岁之间的发展关键里程碑通知给父母。该应用程序使得父母能够跟踪发展里程碑,并确保他们的宝宝正常成长。它会把婴儿每个阶段可以完成的技能按照月份的列表显示出来,使得父母能够记录宝宝获取该技能的日期。该应用程序的主页面显示宝宝当前每个月的成长数据榜。
      该应用的额外特色正是将其安排在本章讲述的主要原因。它展示了如何在隔离存储空间中存储、获取并显示图片。该应用中每个月的列表(从1到24)支持自定义图片作为页面背景,其主要思想是父母能够在合适的时间给宝宝拍摄照片,为每个列表提供一些怀旧的内容。
    
  The Main Page
      主页面如图23.1所示,它包含了一个list box控件,通过它可以链接到24个月份的列表。List中的每个label伴随一个progress bar,它展示当前每个月的发展程度。完成的月份以照片的前景色显示,而未完成的月份则以照片的强调色显示。
DSC0000.png

图23.1 进度条将简单的list box变成了一个有用的面板视图

  注意:
  ? 该应用程序利用了以下两个Settings.cs中定义的设置,Data.Ages展示了24个包含一系列技能的阶段列表。
  ? 在该页面的XAML代码中,数据模板中的进度条直接与每个Age实例的PercentComplete属性进行绑定。但是,为了使每个text block控件有合适的前景色,这里使用了自定义值转换器。本应用程序使用了3个值转换器,在下一节中详述。
  ? 在背后代码中,MainPage_Loaded方法确保选择视图中显示最近的阶段,特别是一旦宝宝超过了9各月,让用户每次都通过滚动条来查看会显让他们觉得很懊恼。这通过BeginInvoke调用来完成,因为在设置数据内容以后立刻操作list box的滚动条,这样可能不行。我们需要在这种方法操作list box之前完成数据绑定。
  ? 在Windows Phone应用程序中,list box最常用的SelectionChanged事件(只有在选定的内容改变以后才会触发,而非点击操作就可以)在这里是不希望出现的。因此,这里使用ListBox_SelectionChanged方法清除刚刚选择的内容,在同一个记录上进行连续点击也是一样。
  Age and Skill
  ? Age 和 Skill这两个类都实现了INotifyPropertyChanged接口,在属性改变时,会触发PropertyChanged事件,如同数据绑定中的数据源。这就使得记录可以显示在主页面上,并且使得details页面(下一节讲述)保持更新,而不用手动进行操作。
  ? 由于Age类中的PercentComplete属性是以Skill列表的每个Date字段为基础的(null意味着未完成,而存在任何日期就表明已经完成),所以,在合适的时间为PercentComplete来触发PropertyChanged事件就显得比较合适。Age类本来可以为每个Skill实例订阅PropertyChanged事件,并且在日期发生改变时,为PercentComplete来触发事件。相反,Age类只需要使用者在相关的日期改变时,调用RefreshPercentComplete就可以了。
  ? Skill类具有一个显式默认构造函数,因为它需要为隔离存储空间进行序列化。一般情况下,C#编译器会生成隐式默认构造函数。但是,在定义非默认的构造函数时,我们必须显式地定义一个默认构造函数(如果需要的话)。
    
  Serialization and Isolated Storage Application Settings
      放置于IsolatedStorageSettings.ApplicationSettings中的每个对象(或者是分配给本书中使用的Settings类的实例)-包括它所有成员的transitive closure-必须要序列化。正如前一章所述,该字典下的内容在ApplicationSettings文件中被序列化为XML。如果存在不可序列化的数据,那么字典中的所有数据将都无法存储。这种错误可能发生于无形,除非我们在调式器中捕获未处理的异常。
      大多数情况下,满足这个需求并不需要额外的工作。这本书中至今没有一个应用需要做特殊的处理来确保它们的设置是可序列化的,包括所有的基本数据类型(string, numeric values, DateTime等等),包括使用了这些基本数据类型的List,以及使用这些数据类型的类,它们都是可序列化的。
      但有的时候,我们需要用自己的方式确保存储的数据是用可序列化的数据类型来描述的。我们可以简单地加入显式默认构造函数来实现,否则的话,我们可能需要花费更多的时间来改变数据类型或者对其进行自定义属性(比如DataMember和IgnoreDataMember,它们使得我们可以自定义类的序列化),我们可以使用IgnoreDataMember属性对其进行标记,从而对其进行排除。
  避免存储相同对象的多个引用!
      对于隔离存储空间应用设置字典中的相同对象,虽然我们可以存储它的多个引用,但是在应用程序下一次运行时,这些引用不会指向同一个实例。那是因为当每个应用被序列化的时候,他的数据被存储为独立的备份。在反序列化时,每个数据的备份变成了不同对象的实例。
     这个正是Baby Milestones使用CurrentAgeIndex设置、而不使用存储Age实例引用设置的原因。在序列化与反序列化后,滚动list box的逻辑再也不起任何作用了,因为Age实例已经不在list box之中。
      我们可以通过对System.Runtime中的一些自定义属性进行标记的方法,在序列化和反序列化中加入用户自定义逻辑。Serialization命名空间:OnSerializing, OnSerialized, OnDeserializing, and OnDeserialized。为了使得我们标记的方法在合适的时间调用,它们必须是public类型的(或者包含一个合适的InternalsVisibleTo属性),并且具有一个StreamingContext参数。
    
  The Details Page
      Details页面如图23.2所示,它在用户点击主页面上的一个age时出现。该页面显示与age相关的技能列表,点击它能够记录获取技能的日期。点击以后,会弹出一个初始化为当天的date picker,如图23.3所示。
DSC0001.png

图23.2 显示第一个月列表的Details页面

DSC0002.png

图23.3 点击第一条记录以后的Details页面

注意

  ? 每条记录中date picker的可见性和text block是基于Skill实例中的Date属性值。这是通过两个值转换器来完成的。
  ? Date picker的值使用双向数据绑定,这对于那些用户控制属性值的方式非常有用。Skill类实例中Date属性的改变不仅自动在date picker中显示出来,而且用户通过UI对date picker作的改变也会自动回馈给Date属性。
  ?该列表使用了自定义的IsolatedStorageHelper类来进行图片文件的加载、保存和删除。如图23.4所示,图片由photo chooser来选择,它将选择的图片以数据流的方式返回。
DSC0003.png

图23.4 Photo chooser支持从媒体库中选择图片或者通过摄像头来拍摄新的图片

  IsolatedStorageHelper的注意点
  ? DeleteFile方法与前一章中删除文件的代码相同,SaveFile方法并不指定图片,而是将输入的二进制流存储为一个新的文件流。与图片相关的部分在LoadFile中,它调用PictureDecoder.DecodeJpeg(在Microsoft.Phone命名空间中)将流转换为ImageSource,从而可以将其设置为Image或ImageBrush的源。
  ? DecodeJpeg方法的速度相当慢,并且它必须在UI线程中调用,所以,这个类会缓存所有它创建的ImageSource,使得下次其文件名被传递给LoadFile时,能够快速返回(相同的ImageSource实例可以被多个UI元素共享,所以复用它并不会带来危险)。
      除了PictureDecoder.DecodeJpeg,可以考虑使用WriteableBitmap.LoadJpeg。后者可以在后台线程中调用,避免在解码一个大的图片时所带来的响应迟滞。WriteableBitmap会在第42章的“Jigsaw Puzzle”中进行介绍。
      LoadFile可以使用一个替代的方法来使用隔离存储空间中的图片构造一个ImageSource。它可以用默认的构造方法来构造BitmapImage,然后调用SetSource方法接收一个IsolatedStorageFileStream实例的流。
      如果我们的应用程序允许从摄像头中保存图片,那么就让用户把它保存到媒体库中,这是一个不错的主意。这样一来,即使应用程序卸载了,拍摄的图片仍旧保留在设备中。而且,一旦图片进入媒体库,用户就可以将其同步到电脑或者使用多种方法来共享(比如上传到Facebook或者SkyDrive)。我们可以简单得调用MediaLibrary.SavePicture来实现。
      重载的DecodeJpeg具有maxPixelWidth与maxPixelHeight参数,他们可以根据性能需求来进行图片的剪裁。但是,当JPEG类型图片的宽度大于高度时,DecodeJpeg会将这两个参数混淆。它会使用maxPixelWidth限制高度,使用maxPixelHeight限制宽度。
    
  
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-65210-1-1.html 上篇帖子: How-to: 利用Visual Studio升级Windows Phone 7工程 下篇帖子: [视频]Silverlight for Windows Phone 7基本开发过程以及Push Button控件的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表