XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2014/06/26

在WinRT下,如何取得圖片檔案的內容或者該圖片的縮圖

往往當把圖片檔案儲存到本機的獨立儲存空間 (Isolated Storage),之後想要顯示該圖片,不過,有些時候這些圖片檔案可能會很大,而我們這個時候只想要顯示這些圖片的縮圖大小,作為讓使用者可以快速大量瀏覽或者選取之用,而不想要取得全尺寸的圖片。

這個時候,就可以用到這兩個方法:

StorageFile.GetThumbnailAsync(ThumbnailMode, UInt32, ThumbnailOptions)
依據縮圖的用途、要求的大小以及指定的選項,擷取檔案經過調整的縮圖影像。

StorageFile.GetScaledImageAsThumbnailAsync(ThumbnailMode, UInt32, ThumbnailOptions)
依據縮圖的用途、要求的大小和指定選項,取得縮放影像做為縮圖。

經過這樣的處理,我們就不再需要取得全尺寸的圖片資源,並且透過 XAML 設定來幫我們做圖片的縮放顯示處理,這樣可以大幅提升整體App的運作速度,當您要處理顯示很多圖片的時候,這是個不錯的優化改善方法。

如何針對 StorageFile物件把它關閉起來

一般我們在處理檔案的時候,若不再需要使用該檔案,就需要將這個資源關閉起來,可是,為什麼 StorageFile物件裡面,卻沒有任何關於 Close 這樣的輔助方法呢?

理由很簡單,因為,StorageFile 只是個抽象的路徑名稱,用來代表檔案系統中的某個檔案,也就是說,當您取得了 StorageFile物件後,例如,使用 StorageFolder.GetFileAsync (使用指定的檔案名稱來取得目前資料夾中的單一檔案。)來取得一個 StorageFile 物件,並不代表了這個檔案已經被開啟並且被鎖住了,這個 StorageFile 物件僅僅只是提供了一個參考到這個檔案的資訊而已。

若您實際取得該StorageFile的資料流(Stream),則您才是開始針對該檔案進行存取動作的開始,不過,當對於該檔案的資料流處理動作完成後,記得要將該資料流做關閉(Close)和 Dispose的動作。

您可以依據您的需求,參考底下四種方法,取得您所需求的資料流
StorageFile.OpenAsync 透過檔案開啟隨機存取資料流。

StorageFile.OpenReadAsync 透過目前的檔案開啟隨機存取資料流來讀取檔案內容。

StorageFile.OpenSequentialReadAsync 透過目前的檔案開啟循序存取資料流來讀取檔案內容。

StorageFile.OpenTransactedWriteAsync 開啟可用於異動寫入作業之檔案的隨機存取資料流。

StorageFile storageFile =
      await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);

    var randomAccessStream = await storageFile.OpenReadAsync();
    Stream stream = randomAccessStream.AsStreamForRead();

在WinRT中,有沒有比較輕鬆容易的處理檔案解決方案

當我們在WinRT系統中,想要處理檔案動作,需要透過 StorageFolder取得一個StorageFile,接著要使用相對應的資料流開啟StorageFile指向的檔案,處理完成後,還要關閉與釋放這個資料流,真的有點繁瑣。

我們可以透過 FileIO Class ( 提供協助程式方法用於讀取和寫入檔案,這些檔案是由IStorageFile型別的物件所表示 ) 類別 與 PathIO Class ( 提供 Helper 方法,以使用絕對檔案路徑或 URI 來讀取和寫入檔案 ),來簡化後半段的動作;例如,我們只想針對該檔案讀取所有的文字內容或者將字串寫入到檔案內。

try
{
    if (file != null)
    {
        string fileContent = await PathIO.ReadTextAsync(filePathOrURI);
    }
}
// Handle errors with catch blocks
catch (FileNotFoundException)
{
    // For example, handle file not found
}

在範例中,filePathOrURI 是區域變數,其包含要讀取之檔案的 URI (例如應用程式 URI "ms-appdata://sampleFile.dat") 或檔案系統路徑 (例如 C:\examplepath\sampleFile.dat)。
在 readTextAsync 完成之後,fileContent 變數會取得檔案的內容做為文字字串。接著您可以依適合的情況處理內容。

關於實際更多用法,您可以參考 檔案存取範例

2014/06/25

在WinRT下,如何使用 StorageFile物件,設定該檔案為唯讀

若您有這樣的需求,想要將某個在 Isolated Storage 內的檔案,設定成為唯讀的屬性,此時,您會需要用到:

StorageFile.Properties
取得物件,用以存取檔案的內容相關屬性。

當取得了 StorageFile.Properties屬性後,他是個屬於 StorageItemContentProperties 類型的物件,代表了 提供檔案之內容相關屬性存取權的物件。

參考下列程式碼,您可以設定檔案為唯讀屬性

String key = "System.FileAttributes";
UInt32 FILE_ATTRIBUTES_READONLY = 1;
var pix = Windows.Storage.KnownFolders.PicturesLibrary;

var file = await pix.GetFileAsync("test.jpg");
String[] retrieveList = new String[] { key };

var props = await file.Properties.RetrievePropertiesAsync(retrieveList);

if (props != null)
{
    var temp = (UInt32)props[key] | FILE_ATTRIBUTES_READONLY;
    props[key] = temp;
}
else
{
    props = new Windows.Foundation.Collections.PropertySet();
    props.Add(key, FILE_ATTRIBUTES_READONLY);
}

await file.Properties.SavePropertiesAsync(props);

不需要經由使用者同意,就可以 WinRT App 存取的檔案系統有哪些?

這是個相當不錯的問題,其實我自己也花了不少時間,才逐步清楚這樣的狀況,尤其是在我要取得 [MCSD: Windows Store Apps Using C# 認證] 的時候,必須要對這樣的情境十分孰悉。

原則上,不需要經過使用者同意,而App可以存取的檔案系統只有 套件資料夾 (Package Folder)與應用程式資料資料夾( App Data Folder),若想要存取本機中的 照片、影片、我的文件資料夾,則您需要設定相對應的功能 (Capability),否則,當您存取這些檔案系統的時候,就會產生錯誤。

其中,
套件資料夾 (Package Folder)
可以透過取得 Windows.ApplicationModel.Package.Current.InstalledLocation StorageFolder物件,例如,您可能要針對該App做到可以內建在 OEM 的機器上,並且要存取 StoreManifest.xml 或者 自訂資料 (Custom Data)檔案,這個 StorageFolder 是指向了您的App實際安裝在本機上的目錄路徑。

應用程式資料資料夾( App Data Folder)
Windows.Storage.ApplicationData 是提供對應用程式資料存放區的存取。 應用程式資料是由本機、漫遊或暫時的檔案與設定所組成。
可以該類別透過取得 Windows.Storage.ApplicationData 中的 LocalFolder, RoamingFolder, TemporaryFolder 這三個屬性。

ApplicationData.LocalFolder 取得本機應用程式資料存放區中的根資料夾。
ApplicationData.RoamingFolder 取得漫遊應用程式資料存放區中的根資料夾。
ApplicationData.TemporaryFolder 取得暫存應用程式資料存放區中的根資料夾。

應用程式資料有三個主要類型:
本機:儲存在裝置上,並且跨更新保存。
漫遊:已複製到使用者安裝應用程式的其他裝置。
暫存:隨時可以由系統刪除。

當然,透過應用程式資料資料夾,也可以存取到本機或者漫遊的應用程式設定容器物件。
ApplicationData.LocalSettings 取得本機應用程式資料存放區中的應用程式設定容器。
ApplicationData.RoamingSettings 取得漫遊應用程式資料存放區中的應用程式設定容器。

存取該App中的任何打包的檔案,此時,您就會需要使用到這個套件資料夾,不過,您需要使用 Visual Studio 2013來設定這些資源檔案的類型屬於內容(Content)形式,並且還要設定複製到輸出資料夾內。

如何判斷 StorageFile 或者 StorageFolder 所指向的檔案是否存於 Isolated Storage 內

之前不論在寫 WinRT 或者 Windows Phone App的時候,一定會遇到這樣的需求,那就是想要檢查在 Isolated Storage 內的某個檔案是否存在,並且根據此一結果,決定接下來要怎麼繼續處理。

當然,這樣的需求已經收錄到我自己整理的 Isolated Storage Class Library 內,當作成一個非常好用的 Helper;不過,那個時候所用的方法是:

            try
            {
                if (使用Mutex == true)
                {
                    StorageMutex.WaitOne();
                }
                var file = await folder.GetFileAsync(string.Format("{0}.txt", filename));
                content = await FileIO.ReadTextAsync(file);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("Filename:{0}, {1}", filename, ex.ToString()));
            }

使用 GetFileAsync 並且使用異常事件捕捉方法 Try-Catch 將這個方法呼叫予以捕捉,一旦所要讀取的檔案不存在,就會產生異常事件,可以根據這個異常事件(類別 FileNotFoundException)來判斷,是否是由檔案不存在所引起的,不過,這樣的作法太不人道了。

現在有個更好的改善方法可以使用,那就是使用 StorageFile.IsAvailable 屬性來判斷,根據 MSDN 上的說法,StorageFile.IsAvailable 是:如果檔案位於本機、已在本機快取或可供下載,則為 True。否則為 false。您說,使用這個方法是不是更加方便了呢?

另外,在 Windows 8.1,也推出了另外一個相當不錯的方法:StorageFolder.TryGetItemAsync,這個方法為,嘗試使用項目名稱來取得目前資料夾中的單一檔案或子資料夾;在以往,我們需要自己寫個擴充方法來做到

  public static class StorageFolderExtensions
  {
    public static async Task TryGetItemAsync(this StorageFolder folder, 
                                                           string name)
    {
      var files = await folder.GetItemsAsync().AsTask().ConfigureAwait(false);
      return files.FirstOrDefault(p => p.Name == name);
    }
  }

現在,我們只需要簡單的使用下列方法,既可以透過 StorageFolder 物件的 TryGetItemAsync 來判斷出,在該目錄下,這個檔案或者子資料夾是否存在了。

StorageFile file = await ApplicationData.Current.LocalFolder.TryGetItemAsync("test") as StorageFile;
 
if (file != null)
{
}

當然,若您開發的Windows Phone 8.1 App,採用的 Universal App,也可以使用這樣的解決方案喔。

關於檔案的 URI 配置

當要存取某個檔案的時候,我們可以使用ApplicationData Class (提供對應用程式資料存放區的存取。 應用程式資料是由本機、漫遊或暫時的檔案與設定所組成)來取得相對應的 StorageFolder物件,接著依序取得檔案所在位置的目錄 StorageFolder物件,接著取得該目錄下的檔案 StorageFile物件,如此,就可以針對該檔案來進行操作了。

不過,我們可以透過檔案的 URI(統一資源識別元)配置,指出該檔案所在的路徑,我們可以參考這些檔案是來自於 [應用程式套件]、[資料資料夾]或[資源]的應用程式檔案。

ms-appx
配置參考來自應用程式套件的應用程式檔案 (請參閱應用程式套件與部署)。
這類檔案通常為靜態影像、資料、程式碼及配置檔。


        void PopupForSheetMusic_Closed(object sender, object e)
        {
            this.imgSheetMusic.Source = new BitmapImage(new Uri("ms-appx:///Assets/Images/Core/btn_sheet music_n.png"));
        }


        public MyChannelData()
        {
            this.ID = RandomString(20);
            this.OrderNo = 99999;
            this.Title = "";
            this.CreateDatetime = DateTime.Now;
            this.RecordLength = TimeSpan.FromSeconds(0);
            this.GetProductInfo_Data = new GetProductInfo_Response_Data();
            this.RecordingType = Business.RecordingType.VIDEO;
            this.Cover = "ms-appx:///Assets/Images/Core/img_voice_picture.png";
        }


ms-appdata
使用 ms-appdata 配置來參考應用程式檔案,這些檔案來自應用程式的本機、漫遊及暫存資料資料夾。

若想要讀取[本機]、[暫存]、[漫遊]這三個資料夾,可以使用下列的 URI

本機資料夾  ms-appdata:///local/
暫存資料夾  ms-appdata:///temp/
漫遊資料夾  ms-appdata:///roaming/

                    if (xi.Count >= 1)
                    {
                        di.Cover = xi[0].GetProductInfo_Data.ProductCover;
                        di.Cover = string.Format("ms-appdata:///local/CoverImages/{0}.png", xi[0].GetProductInfo_Data.ProductID);
                    }
                    if (xi.Count >= 2)
                    {
                        di.Cover2 = xi[1].GetProductInfo_Data.ProductCover;
                        di.Cover2 = string.Format("ms-appdata:///local/CoverImages/{0}.png", xi[1].GetProductInfo_Data.ProductID);
                    }
                    if (xi.Count >= 3)
                    {
                        di.Cover3 = xi[2].GetProductInfo_Data.ProductCover;
                        di.Cover3 = string.Format("ms-appdata:///local/CoverImages/{0}.png", xi[2].GetProductInfo_Data.ProductID);
                    }


ms-resource

使用 ms-resource 配置來參考應用程式資源,這類資源通常是字串資源。

參考來源:http://msdn.microsoft.com/zh-tw/library/windows/apps/jj655406.aspx

如何在 Windows Store App 與 Windows Phone App上,取得裝置上的唯一 ID 代碼

如何在 Windows Store App 與 Windows Phone App上,取得裝置上的唯一 ID 代碼,相信很多在寫App的朋友都會遇到這樣的問題,我這裡整理出這兩個平台取得裝置上唯一ID代碼 ( Device ID)的方法。

Windows Phone

        public static string GetHardwareId()
        {
            string ss = HostInformation.PublisherHostId;
            return ss;
        }

其中您可以參考 MSDN 上的說明 HostInformation.PublisherHostId property

Windows Store ( WinRT )

        /// 
        /// 取得裝置的唯一識別代碼
        /// 
        /// 
        public static string GetHardwareId()
        {
            var _Token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
            var _Id = _Token.Id;
            var _Reader = Windows.Storage.Streams.DataReader.FromBuffer(_Id);
            var _Bytes = new byte[_Id.Length];
            _Reader.ReadBytes(_Bytes);

            string ss = BitConverter.ToString(_Bytes).Replace("-", "");
            return ss;
        }

其中,在MSDN上的描述為 : HardwareIdentification.GetPackageSpecificToken 取得表示目前硬體的硬體識別項 (ASHWID)。 為每個應用程式封裝傳回的 ASHWID 會不同。換句話說,當這個應用程式開發介面由兩個來自不同封裝的應用程式呼叫時,就會傳回不同的識別項。當同一個封裝的兩個應用程式呼叫它時,它會傳回相同的識別項。

只要7天,一步一步地學會 MVC (Model view controller) 開發技術

光看字面意義,真的滿吸引人的 『Learn MVC (Model view controller) Step by Step in 7 days』,這好像是台灣在賣藥品或者保養品的廣告;只要短短7天,本商品就可以幫助您年輕10歲。

不過,師父領進門,修行在個人,再好的入門文章、技巧、教學影片、課程,若您之後不自己來修練,說真的,還是無效的。

來看看這個作者的前五天的課程規劃

Day 1: -Controllers, strong typed views and helper classes
Day 2: - Unit test, routing and outbound URLS
Day 3:- Partial views, Data annotations,Razor, Authentication and Authorization
Day 4:- JSON, JQuery, State management and Asynch controller
Day 5:- Bundling , Minification , ViewModels,Areas and Exception handling
Day 6: - Display Modes,MVC OAuth,Model Binders,Layout and Custom view engine

真的滿不錯的,若您實際有打開這些課程連結,您就會發現到作者是相當的用心,每天的課程有著 Youtube 的影片,透過影片的學習,快速地聽老師講解一遍,甚至可以看到老師對於範例的操作過程,有助於您對於 ASP.NET MVC 的觀念與作法上的了解。若您聽不太懂英文,真的有些抱歉,因為,這些影片在 Youtube 上沒有提供翻譯字幕。

最後,這是一個值得推薦的 ASP.NET MVC 課程 (免費的喔 )

可來伴奏王 App 的開發心得

去年九月,公司指派了一個案子,可來伴奏王 App ,這是一個 Windows Store 的App,從剛開始接到客戶 RFP & Wireframe 架構圖來看,困難度似乎沒有這麼高,而且 UX 的部分,也是有專門的人原來設計,我們只需要依照設計出來 UX 切圖,套用到這個 Windows Store App上。





事情如果這麼單純就好,如果是這樣,我也就不會從開發可來伴奏王 App的過程中,學習到各種不同的知識與技能,並且應用這些知識和技能,通過了微軟 MCSD:Windows Store Apps 認證;而我會想要去考 MCSD 認證,也是因為開發可來伴奏王 App過程中,發現到要能夠開發出這樣的App,幾乎用到的 WinRT 所提供的 70% 以上的API,也就是說,若您對於 WinRT生態不是十分孰悉,開發起來,必定是痛苦萬翻;不過,也不要擔心,只要您開發出來了,那麼,這些API您也就學會了。

其中這個App會與硬體廠商做到OEM內建機制,這部分也讓我吃足了苦頭,之前也有做過一的Windows Store App,也是與硬體OEM做到內建,幾乎沒有遇到太大的問題,只是一開始 K 文件比較辛苦,可是在伴奏王這個App,OEM硬體廠商卻怎麼也無法預載他們的機器中,最後,只好請微軟的人幫忙研究與分析,原來是專案中有用到資源檔案,他的檔案名稱是中文字,導致無法預載。

而這個App最為複雜的部份,就是媒體撥放器的部分,其中遭遇到了多音軌音樂不同步、音樂游標不同步、手寫筆記、互動撥放等許多功能,整個糾結再一起,說真的,有如脫韁野馬,也有如滔滔江水,綿延不決,導致一發不可收拾;很高興的是客戶相當的有耐心,與我合作一起把問題逐一解決。

當然,未來的文章中,也會將這個專案中的許多不錯的技巧與做法,寫出來與大家分享。

底下是可來伴奏王的功能說明,當然,若您有 Windows 8.1作業系統,您也可以安裝起來使用看看:
說明
「伴奏王」是一個跨世紀的音樂伴奏網絡平臺,也是一個創新的音樂伴奏工具,不論您是音樂初學者、業餘音樂人士、或是專業的演奏家,「伴奏王」能改變您對音樂練習的傳統刻板印象,「伴奏王」將讓您驚豔音樂學習時的豐富樂趣,並獲得實際又有效的練習成果。

音樂學習過程當中最難受的部分就是得忍受自己一人孤單又乏味的練習,想找人一起練習總是喬不定時間,花錢請伴奏又是一筆龐大的開銷。此時,「伴奏王」正是您所需要的音樂產品,一個能讓您隨時帶著走的專業音樂伴奏軟件。

主要功能:
*音樂伴奏 樂在其中
專業製作的高質感音樂伴奏(非一般網絡MIDI品質),讓您的音樂練習不再枯燥乏味。每一個樂器分部都可以獨立開啟與關閉,就像是使用卡拉OK一樣的簡單。如此前所未有的產品體驗,將一舉改變您的練習方式,豐富您的音樂經驗。

*「隨點即播」- 手點到哪 音樂播到哪
電子樂譜移動光標與音樂播放完全同步,無論第幾頁、第幾行或是任一小節,只要手指輕觸屏幕於想要播放的段落點,音樂便會立即跳至點選處並播放音樂,就是這麽簡單!就是這麽神奇!

*節拍器
每一首曲子均可使用音樂互動式的音樂節拍器搭配練習,即使在漸快、漸慢的段落,內建節拍器依然可以讓您輕鬆地跟隨音樂的節奏。

*自動翻頁
您不再需要擔心翻譜的問題!「自動翻頁」的功能會在每一個需要翻頁的地方跳至下一個頁面,包含樂譜上的反覆記號段落。

*樂譜光標指示器
「伴奏王」平臺的樂譜都有光標顯示的功能,光標顯示與音樂播放能完全地同步,如果您對樂曲還不是那麽熟悉,這個功能可以幫助您精準掌握樂曲的進行。當對樂譜有足夠的熟悉度之後,您也可以選擇關閉此功能。

*數位譜紙 多樣選擇
內建數種不同顏色與風格的電子數位譜,豐富您的曲目收藏,建立您的個人風格。

*樂曲搜尋 輕而易舉
使用包括作曲家、類型、風格、樂器種類、難易度、出版社..,等,多樣之交叉組合過濾搜尋方式,能輕鬆的找到您所需要的曲子。

結合全球一流的音樂出版社的專業音樂伴奏產品,「伴奏王」提供您從古典到流行,從爵士到宗教音樂,從初級到專業的音樂演奏需求。我們精心制作最優質的曲目以及最精美的電子樂譜,以提供不同樂器的多樣練習需求。
顯示較多的項目
功能
音樂伴奏 樂在其中
「隨點即播」- 手點到哪 音樂播到哪
內建節拍器
自動翻頁
樂譜游標指示器
數位譜紙 多樣選擇
樂曲搜尋 輕而易舉