zoukankan      html  css  js  c++  java
  • 《101 Windows Phone 7 Apps》读书笔记BABY NAME ELIMINATOR

    课程内容

    Ø本地数据库

    Ø在应用程序中处理数据

     

        Baby Name Eliminator是一种通过输入性格特征而获取婴儿名字的应用程序(我和我的妻子用这种方法来为两个儿子取名字)。与采用头脑风暴的方式取名字、而后又担心错过了最好的名字不同,本应用程序使得我们利用淘汰法为婴儿取名。

        Baby Name Eliminator建立在一个巨大的数据库之上,它存放了美国范围内使用的36,065个男孩名字和60,438个女孩名字。在我们选定性别以后,应用程序会使用多种过滤器来缩小名字列表。这些过滤器建立在以下几个因素的基础之上:每个名字的受欢迎程度、名字的开头和结束字母以及该名字首次使用的时间。一旦对列表进行过滤之后,我们就可以一个个得对名字进行排除,直到做出最后的选择。

        在为孩子取名字时,我们会进行多次考虑,排除那些明显不好的,留下我们犹豫不决的。在我们静下心来对待20个可选择的名字时,我和妻子各自选择认为最好的5个。对于第一个儿子,我们选取了共同的名字,所以就这样下了最后的决定。如果你和妻子都有Windows Phone手机,那么各自选择名字、直到列出候选名单,这种方式将非常有趣。

        那么,这个名字数据库从何而来呢?答案是社会安全局,它可以提供1880年以来几乎每个社会安全卡上的姓名。这张表有几点需要说明:

    ➔ 出于隐私的原因,只包含给定年份中使用5次以上的名字。

    ➔ 单个字符的名字不包括在内。

    ➔ 1937年之前出生的许多人没有社会安全卡,所以那些年的数据不全。

    ➔ 相同名字的不同拼写被视为不同的名字。

    ➔ 数据未经加工,也未经排错。有时候申请表上的性别是错误的,导致女孩名字列表上出现男孩子的名字,同时相反的情况也存在。除此之外,一些名字被记录为“未知”,“未命名”,或者是“婴儿”。这些情况可以通过限制列表的前1000个名字来解决。

        为使能这种过滤,本应用程序利用了两个本地数据库-一个存放男孩名字,另一个存放女孩的名字。

     

    Working with Local Databases

        Windows Phone 7缺少对本地数据库的支持是其公认的缺点之一。鼓励应用程序与服务器端的数据库配合工作,但是这对于开发者来说会引入额外的负担,对于用户来说会带来更多的麻烦(延时,数据连接,潜在的数据流量成本)。幸运的是,我们可以选择第三方数据库。我最喜欢的是开源的SQLite for Windows Phone 7,它由Dan Ciprian Ardelean所创建。我们可以在以下网页中进行查看:http://sviluppomobile.blogspot.com/2010/03/sqlite-for-wp-7-series-proof-of-concept.html并通过以下链接获取最新的版本:http://www.neologics.eu/Dan/WP7_Sqlite_20.09.2010.zip它包含了C#源代码和一个Community.CsharpSqlite.WP.dll文件,我们可以在工程中对它进行引用。它当然不可能没有缺陷,但是在多数情况下它都工作得非常好(比如本应用程序)。

        SQLite for Windows Phone 7从隔离存储空间中读取或者写入数据库文件。如果我们想要把填充好数据的数据库和应用程序一起部署,我们可以将数据库文件包含到工程中,并且把Build Action设置为Content。在运行时,第一次使用SQLite之前,我们的应用程序获取文件,并把它存储到隔离存储空间中。在工程中要以内容的方式访问文件,我们可以调用Application. GetResourceStream。

    如何创建一个随应用程序部署的包含数据库的.bd文件?

       以下就是在Windows Phone应用程序中的方法:

    1. 执行CREATE TABLE和INSERT命令,使用SQLite产生一个数据库。

    2. 利用隔离存储空间的API,获取SQLite存储到隔离存储空间中的.db文件的原始数据。

    3. 从Visual Studio debugger拷贝字符数据作为Base64编码的字符串,使用另外的(桌面)程序解码,将它们存储到需要的.db文件中。

    注意:

    ➔ 在执行大量的数据库操作时,为了使得用户界面可响应,与SQLite的交互是通过BackgroundWorker的后台线程来完成的,通过回调函数来获取成功/失败信息。

    ➔ 传递给ExecuteScalar和ExecuteQuery的命令字符串可以是SQL命令,比如:SELECT COUNT(*) FROM table

    ➔ ExecuteQuery是一个通用的方法,其通用参数T必须是一个类,且具有一个与查询中选择的列相一致的属性。

        Application.GetResourceStream与工程中包含的文件配合工作,文件的Build Action设置为Content,或者Build Action设置为Resource。对于后者,传入的URI必须符合下面的语法:/dllName;component/pathAndFilename

        注意,dllName可以引用.xap文件中的任何dll,只要它包含需要的资源。但是,不能包含dll后缀。

        对于本应用,位于工程根目录的男孩名字数据库(Boys.db)的DatabaseName字符串如下所示,

        /WindowsPhoneApp;component/Boys.db

        但是,如果这样的话,列表24.1使用的SaveFile就必须更改,因为DatabaseName字符串对于隔离存储空间来说,不再是一个有效的文件名。

     

    Application.GetResourceStream与Assembly.GetManifestResourceStream

        我们可能偶然发现Assembly.GetManifestResourceStream API是作为读取包含在应用中的文件的方法。这样是可行的,但是仅仅限于那些Build Action设置为 Embedded Resource的文件(而不是设置为Resource)。

        但是,传递给GetManifestResourceStream的字符串具有它独特的语法:dllName.filename中dllName是包含embedded resource的DLL的名字。那是因为在命名每个embedded resource 时,C#编译器自动将DLL名字(减去.dll扩展名)前置到文件名中(你可以通过诸如.NET Reflector工具来打开DLL查看名字)。本应用中,两个有效的字符串是“WindowsPhoneApp.Boys.db”和“WindowsPhoneApp.Girls.db”。

        相对于这种方法来说,Application.GetResourceStream更加灵活。与其他那些将文件作为嵌入式资源的机制相比,使用作为内容方式文件的GetResourceStream方法更加受人欢迎,因为资源会增加DLL文件的大小,并且那样会增加应用程序的加载时间。

     

    The Filter Page

        我们可以通过浏览包含的源代码来查看应用程序的主页面,但我们首先要查看利用DatabaseHelper类的过滤页面。过滤页面如图24.1所示,显示了列表中有多少个名字,然后,我们能够利用一些选项来过滤它,这些选项可以映射为SQL查询命令,并作用在数据库上(男孩与女孩名字在之前的主页面上进行选择)。

    image

    图24.1

        如图24.2所示,每个按钮会揭示一个新的窗口或者页面,那使得用户可以控制每个相关的过滤条件。点击名字的数量会揭示真实名字的列表,如图24.3所示。该列表不能进行交互式的排除,但是,那可以在主页面中来完成。

    image

    图24.2

    image

    图24.3

    注意:

    ➔ 点击按钮时弹出的对话框是由Dialog用户控件所创建的,这可以在应用程序的源代码中看到。字幕的网格由LetterGrid用户控件所创建。这里的网格与第18章“Cocktails”中的QuickJumpGrid控件很类似。

    ➔ 5个过滤按钮是toggle类型的,它们的IsChecked状态由背后的代码来管理。如果一条过滤条件被激活,它相关的按钮会被检查(高亮),使得用户可以在不用点击每个按钮的情况下看到它,也不用对其过滤条件进行双重检查。

    ➔ 在后台线程执行查询时,进度条和它相关的用户界面会显示出来,如图24.4所示。因为它不会占据整个屏幕,所以如果用户不在意等待当前名字的话,它允许用户继续工作。

    ➔本工程包含了两个数据库(Boys.db 和Girls.db),它们具有相同的模式。它们只包含一张名为Names表,该表具有三个列:Name,BestRank(它单个年份中最好的排名)和FirstYear(在社会安全数据库中首次出现的年份)。

    ➔ 刷新名字数量的查询命令为“SELECT COUNT(*) FROM Names”,它可以具有WHERE子句,它们建立在那些由过滤法则决定的设置之上。

    ➔ 显示真实名字的查询命令为“SELECT Name FROM Names”,它同样可以具有WHERE子句。因此,与ExecuteQuery 一同使用的Record类具有单字符串的Name属性。ToString方法允许Record集合可以作为没有任何数据模板的list box预览的数据源,因为text block中内置的ToString已经足够。

    ➔正如前一章中的date picker一样,本应用对每个字符选择都使用双向数据绑定。

  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/dearsj001/p/101App4WP7_BABYNAME.html
Copyright © 2011-2022 走看看