XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

2014/06/28

C# 支援那些逃脫字元 escape character

C# 定義了底下可以使用的逃脫字元,您可以在字串表示式中,使用這些逃脫字元來標示出特別的字元:

\' - 單引號
\" - 雙引號
\\ - 反斜線\
\0 - Unicode 0
\a - 警告聲
\b - 退回鍵
\f - 強制跳頁
\n - 換行
\r - 歸位
\t - Tab
\v - 垂直定位鍵
\uxxxx - Unicode 逃脫字元,用來表示 Unicode xxxx 數值編碼所代表的文字
\xn[n][n][n] - Unicode 逃脫字元,用來表示 Unicode xxxx 十六進位數值編碼所代表的文字

哪裡可以取得 C# 語法的規格文件

寫程式到某個階段,我喜歡把這些工具、程式語言做個深入透徹的了解,這樣,日後再使用這個程式語言開發的時候,就可以盡情地善用這個工具所提供的各項特色與優勢,不過,C#的語言定義文件在哪裡,是否有這個文件呢?

有兩個地方可以取得,微軟與ECMA。在 ECMA 的 Ecma-334 的文件,就是 C# 5.0 的語言定義文件,不過,這裡只有 PDF 格式文件。在微軟的下載中心 (Microsoft Download Center),您可以取得 Word 版本的 C# 5.0 語言定義文件。

2014/06/27

有沒有關於 c# async/await 得不錯文章可以參考

在C# 5.0的時候,我們可以使用 async / await 來幫助我們解決非同步(例如,讀寫檔案系統上的檔案、抓取網路上的資源、存取 Restful API等等)程式設計上的需求,在以往沒有 async / await 功能的時候,我們要處理非同步的功能,一來會造成程式不太好寫,二來程式碼會變得又臭又長,而且不太好維護與除錯和控制。

現在,我們可以透過 C# 的非同步程式設計 async / await 來解決長久以往困擾大家的問題,不過,若只是一知半解,往往會造成一個好用的工具,卻無法幫助您解決實際上的問題;不要想太多,現實上沒有速成、簡單的技巧,讓您可以靈活運用 async / await 這個工能,花點時間,深入研究 async /await 這個特色,一定會對於您日後程式開發上,會相當有幫助的。

這裡有些不錯的文章,是您要學習 C# 非同步處理 async / await 必須要看過的:




這個文章是 MSDN 上關於C# 非同步使用說明,很多人不喜歡或者不去看 MSDN 的文章,這是您使用微軟開發工具要近身為專業或者大師級的工程師之一大障礙,這就像練武之人,只練拳腳(到網路上找些範例程式碼,剪下來,貼上去 Ctrl + C Ctrol + V),而不練內功(徹底瞭解不同功能的原理與變化,並且有著哪寫潛在的問題,這就需要不斷的閱讀不同的文章與書籍,當然,基礎內功的修練,官方的文章與手冊,是必須要閱讀的),是無法成為武術宗師的,往往這樣的人,最後就只能夠在廟會廣場或者夜市中,表演胸口碎大石,賺點賞金來過河;練拳不練功,到老一場空,這句話一定要放在心裡,必且做到,千萬不要只是放在心裡尊敬著,只要嘴巴說喔。

在這份官方教材中,告訴您如何使用 Async 來幫助您改善程式因為處理非同步需求時候,會造成您的程式被凍結的現象,並且讓您知道如何簡單、方便地透過 Async 來做到以往您做不到的事情;另外,您也可以明瞭 Thread 與 Async 之間是如何處理的、如何取得非同步呼叫的回傳結果、Async / Await 是甚麼,他們之間要如何搭配等等,這些都是您要使用 Async / Await 方法的時候,必須要知道。

想要更加深入這方面的議題,請參考底下 MSDN雜誌上的文章

Easier Asynchronous Programming with the New Visual Studio Async CTP

Asynchronous Programming: Pause and Play with Await

Asynchronous Programming: Understanding the Costs of Async and Await

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