《101 Windows Phone 7 Apps》读书笔记-BABY MILESTONES
課程內容
?圖片的讀寫?序列化
?雙向數據綁定
??? Baby Milestones將嬰兒從出生到2歲之間的發展關鍵里程碑通知給父母。該應用程序使得父母能夠跟蹤發展里程碑,并確保他們的寶寶正常成長。它會把嬰兒每個階段可以完成的技能按照月份的列表顯示出來,使得父母能夠記錄寶寶獲取該技能的日期。該應用程序的主頁面顯示寶寶當前每個月的成長數據榜。
??? 該應用的額外特色正是將其安排在本章講述的主要原因。它展示了如何在隔離存儲空間中存儲、獲取并顯示圖片。該應用中每個月的列表(從1到24)支持自定義圖片作為頁面背景,其主要思想是父母能夠在合適的時間給寶寶拍攝照片,為每個列表提供一些懷舊的內容。
?
The Main Page
??? 主頁面如圖23.1所示,它包含了一個list box控件,通過它可以鏈接到24個月份的列表。List中的每個label伴隨一個progress bar,它展示當前每個月的發展程度。完成的月份以照片的前景色顯示,而未完成的月份則以照片的強調色顯示。
圖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所示。
圖23.2 顯示第一個月列表的Details頁面
圖23.3 點擊第一條記錄以后的Details頁面
注意
? 每條記錄中date picker的可見性和text block是基于Skill實例中的Date屬性值。這是通過兩個值轉換器來完成的。
? Date picker的值使用雙向數據綁定,這對于那些用戶控制屬性值的方式非常有用。Skill類實例中Date屬性的改變不僅自動在date picker中顯示出來,而且用戶通過UI對date picker作的改變也會自動回饋給Date屬性。
?該列表使用了自定義的IsolatedStorageHelper類來進行圖片文件的加載、保存和刪除。如圖23.4所示,圖片由photo chooser來選擇,它將選擇的圖片以數據流的方式返回。
圖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限制寬度。
?
轉載于:https://www.cnblogs.com/dearsj001/archive/2012/08/12/101App4WP7_MILESTONE.html
總結
以上是生活随笔為你收集整理的《101 Windows Phone 7 Apps》读书笔记-BABY MILESTONES的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP获得真实客户端的真实IP REMO
- 下一篇: 开始使用Python编程