XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

2017/11/22

Xamarin.Forms / .NET Standard 體驗之旅 4 : QR Code 條碼掃描

對於已經具備擁有 .NET / C# 開發技能的開發者,可以使用 Xamarin.Forms Toolkit 開發工具,便可以立即開發出可以在 Android / iOS 平台上執行的 App;對於要學習如何使用 Xamarin.Forms & XAML 技能,現在已經推出兩本電子書來幫助大家學這這個開發技術。
這兩本電子書內包含了豐富的逐步開發教學內容與相關觀念、各種練習範例,歡迎各位購買。
Xamarin.Forms 電子書
想要購買 Xamarin.Forms 快速上手 電子書,請點選 這裡

想要購買 XAML in Xamarin.Forms 基礎篇 電子書,請點選 這裡


在 Xamarin.Forms / .NET Standard 體驗之旅 4 的文章中,我們將要來測試每次進行 Xamarin.Forms 實戰課程,大家最想要學習與使用的這個 NuGet 套件:ZXing.Net.Mobile,也就是要開發出具有跨平台的條碼掃描程式。
我們從這個套件在 NuGet 官網上的內容可以看的出來,這個 NuGet 套件尚未支援 .NET Standard 標準類別庫,而是之前的可攜式 PCL 類別庫,不過,因為 .NET Standard 2.0 類別庫也支援可以使用 PCL 類別庫,因此,我們來測試看看,這個套件可否用於 Prism Template Pack 2.0.7 產生的 Xamarin.Forms 跨平台專案,並且進行一維條碼或者二維條碼 QR Code。
Realm NuGet

測試範例專案原始碼

這篇文章中的測試範例專案原始碼,您可以從這裡取得 https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFQRCode

開始建立專案

請點選功能表 [檔案] > [新增] > [專案],此時,您會看到底下的 [新增專案] 對話視窗。
我們點選 Prism Template Pack 提供的 Xamarin.Forms 專用的專案樣板,請點選 [已安裝] > [Visual C#] > [Prism] > [Prism Blank App (Xamarin.Forms)]。
接著在名稱欄位輸入該專案名稱後,點選 [確定] 按鈕,以建立此練習專案。
然後,在 [PRISM PROJEC WIZAD] 對話窗中,選擇您要跨平台的作業系統,容器 (Container) 這裡,我個人喜歡與習慣使用 Prism,您可以選擇您自己要用的容器,最後,點選 [CREATE PROJECT] 按鈕。
.NET Standard Xamarin.Forms Project

安裝 ZXing.Net.Mobile.Forms NuGet 套件

在這裡,請使用滑鼠右建,點選剛剛建立好的共用類別庫(也就是 .NET Standard 標準類別庫)節點,選擇 [管理方案的 NuGet 套件] 項目。
在 [瀏覽] 標籤頁次上,輸入 ZXing.Net.Mobile 這個關鍵字,搜尋出這個套件。請選擇 ZXing.Net.Mobile.Forms 這個套件,要來安裝到 .NET Standard 專案內。
從下圖中,我們可以看到這個套件並不支援 .NET Standard,不過,我們還是要把這個套件安裝到 .NET Standard 專案內。
ZXing.Net.Mobile.Forms
當我們點選 [安裝] 按鈕之後,會看到 Visual Studio 會提示您這樣會安裝那些相依性的套件。
.NET Standard Xamarin.Forms Project

修正首頁頁面

我們對於這個應用程式的設計構想是這樣的,當這個應用程式一旦啟動,會在螢幕上顯示一個按鈕,和一些 Label 欄位,這些 Label 欄位是要用來顯示掃描到的條碼資訊。因此,當使用者按下 Scan... 按鈕之後,就會切換到另外一個頁面,這個頁面將會使用 ZXingScannerView 用來進行協助我們做到條碼掃描的工作。
安裝好套件之後,讓我們打開 MainPage.xaml 檔案,修改XAML內容。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFQRCode.Views.MainPage"
             Title="ZXing.Net.Mobile 條碼掃描">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Label
            Text="條碼類型"/>
        <Label
            Text="{Binding BarcodeFormatType}"/>
        <Label
            Text="{Binding BarcodeResult}"/>
        <Button
            Text="Scan..."
            Command="{Binding ScanCommand}"/>
    </StackLayout>

</ContentPage>
接著我們打開 MainPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
這裡特別說明的是,當掃描條碼的頁面有掃描到結果,我們是透過頁面導航機制提供的相關事件,進行讀取來自掃描頁面的掃描結果。因此,您可以觀察 OnNavigatingTo 方法,我們將會透過比對 parameters.ContainsKey("Result")表示式,確認該事件可以讀取掃描結果內容。
namespace XFQRCode.ViewModels
{

    public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string BarcodeFormatType { get; set; }
        public string BarcodeResult { get; set; }

        public DelegateCommand ScanCommand { get; set; }

        private readonly INavigationService _navigationService;

        public MainPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;

            ScanCommand = new DelegateCommand(() =>
            {
                _navigationService.NavigateAsync("ScanPage");
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {
            if(parameters.ContainsKey("Result"))
            {
                var fooReslut = parameters["Result"] as Result;
                BarcodeFormatType = fooReslut.BarcodeFormat.ToString();
                BarcodeResult = fooReslut.Text;
            }
        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {

        }

    }

}

新增條碼頁面

接下來,我們需要新建立一個頁面,ScanPage,我們將會在這個頁面上使用 ZXingScannerView 用來進行協助我們做到條碼掃描的工作。
當新增完成 ScanPage 頁面,讓我們打開 ScanPage.xaml 檔案,修改XAML內容。
首先我們先宣告一個新的命名空間,xmlns:Zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms",這樣,我們就可以使用這個命名空間前置詞參考到這個 ZXingScannerView 控制項。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:Zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="XFQRCode.Views.ScanPage"
             Title="進行條碼掃描中..."
             >

    <Grid
        >
        <Zxing:ZXingScannerView
            HorizontalOptions="Fill"
            IsAnalyzing="{Binding IsAnalyzing}"
            IsScanning="{Binding IsScanning}"
            Result="{Binding ScanResult, Mode=TwoWay}" 
            ScanResultCommand="{Binding ScanResultCommand}"
             />
        <Zxing:ZXingDefaultOverlay Opacity="0.9" ShowFlashButton="False" />
    </Grid>
</ContentPage>
接著我們打開 ScanPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
一旦條碼有掃描到之後,將會執行 ScanResultCommand 的委派方法,不過,您需要特別注意,我們需要使用 Device.BeginInvokeOnMainThread 方法,將您要執行的程式碼,全部都指定在 UI (Main) Thread 上運行。
namespace XFQRCode.ViewModels
{

    public class ScanPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public bool IsAnalyzing { get; set; } = true;
        public bool IsScanning { get; set; } = true;
        public Result ScanResult { get; set; }
        private readonly INavigationService _navigationService;

        public DelegateCommand ScanResultCommand { get; set; }

        public ScanPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;


            ScanResultCommand = new DelegateCommand(async () =>
            {
                Device.BeginInvokeOnMainThread(async () =>
                {
                    IsAnalyzing = false;
                    IsScanning = false;
                    var fooPara = new NavigationParameters();
                    fooPara.Add("Result", ScanResult);
                    // 回到上頁,並且把掃描結果帶回去
                    await _navigationService.GoBackAsync(fooPara);
                });
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {

        }

    }
}

進行測試

最後,設定預設起始專案為 Android 專案,並且需要使用實體手機來進行測試。

Acr.UserDialogs 執行結果 Acr.UserDialogs 執行結果


了解更多關於 [Xamarin.Android] 的使用方式
了解更多關於 [Xamarin.iOS] 的使用方式
了解更多關於 [Xamarin.Forms] 的使用方式
了解更多關於 [Hello, Android:快速入門] 的使用方式
了解更多關於 [Hello, iOS – 快速入門] 的使用方式
了解更多關於 [Xamarin.Forms 快速入門] 的使用方式


2017/11/15

Xamarin.Forms / .NET Standard 體驗之旅 3 : 使用 PCLStorage 元件進行檔案的讀取與寫入

在 Xamarin.Forms / .NET Standard 體驗之旅 3的文章中,我們將要來測試這個最常用的 NuGet 套件:PCLStorage。
我們從這個套件在 NuGet 官網上的內容可以看的出來,這個 NuGet 套件本身是支援 PCL 可攜式類別庫的,那麼,這樣的 PCL 套件,是否可以能夠在 .NET Standard 標準類別庫,並且提供給 Xamarin.Android / Xamarin.iOS / UWP 平台系統來使用,我們來測試看看。
PCLStorage NuGet

測試範例專案原始碼

這篇文章中的測試範例專案原始碼,您可以從這裡取得 https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/NETStdPCLStorage

開始建立專案

請點選功能表 [檔案] > [新增] > [專案],此時,您會看到底下的 [新增專案] 對話視窗。
我們點選 Prism Template Pack 提供的 Xamarin.Forms 專用的專案樣板,請點選 [已安裝] > [Visual C#] > [Prism] > [Prism Blank App (Xamarin.Forms)]。
接著在名稱欄位輸入該專案名稱後,點選 [確定] 按鈕,以建立此練習專案。
然後,在 [PRISM PROJEC WIZAD] 對話窗中,選擇您要跨平台的作業系統,容器 (Container) 這裡,我個人喜歡與習慣使用 Prism,您可以選擇您自己要用的容器,最後,點選 [CREATE PROJECT] 按鈕。
.NET Standard Xamarin.Forms Project

安裝 PCLStorage NuGet 套件

在這裡,請使用滑鼠右建,點選剛剛建立好的方案節點,選擇 [管理方案的 NuGet 套件] 項目。
在 [瀏覽] 標籤頁次上,輸入 PCLStorage 這個關鍵字,搜尋出這個套件。這個 PCLStorage 套件圖示為一個綠色瓶子樣子。
從下圖中,PCLStorage 套件本身僅支援 PCL Profile259,並且不支援 .NET Standard 標準類別庫,不過,沒有關係,我們嘗試繼續安裝下去,因此,在右方區域,勾選 [NETStdPCLStorage] 這個 .NET Standard 專案(您可以不用勾選原生專案)
.NET Standard Xamarin.Forms Project
.NET Standard Xamarin.Forms Project
當我們點選 [安裝] 按鈕之後,會看到 Visual Studio 會提示您這樣會安裝那些相依性的套件。
.NET Standard Xamarin.Forms Project

修正 View / ViewModel 開始使用 Acr.UserDialogs

安裝好套件之後,讓我們打開 MainPage.xaml 檔案,修改XAML內容。
這裡,我們僅在 StackLayout 版片配置內,加入3個按鈕項目,並且設定 Command 屬性,要綁定 ViewModel 內類型為 DelegateCommand 的特定物件,這三個按鈕分別會將文字輸入盒輸入的文字進行儲存到指定檔案中、清空文字輸入盒、從檔案中將內容讀取出來,並且置換掉文字輸入盒的內容。
透過這三個按鈕,我們可以確認資料是否真的有擁有儲存在手機檔案中,當然,您也可以於儲存到檔案中之後,關閉這個程式,接著重新啟動,看看是否可以從檔案中讀取出來。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NETStdPCLStorage.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Entry Text="{Binding MyEntry}"/>
        <Button Text="Save" Command="{Binding SaveCommand}"/>
        <Button Text="Clean" Command="{Binding CleanCommand}"/>
        <Button Text="Load" Command="{Binding LoadCommand}"/>
    </StackLayout>

</ContentPage>
接著我們打開 MainPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
這裡進行檔案文字內容的讀取與寫入的程式碼,全部都是從 PCLStorage 官方網站上複製下來的,我們在此就不再多做說明。
namespace NETStdPCLStorage.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {


        #region MyEntry
        private string _MyEntry = "";
        /// <summary>
        /// MyEntry
        /// </summary>
        public string MyEntry
        {
            get { return this._MyEntry; }
            set { this.SetProperty(ref this._MyEntry, value); }
        }
        #endregion

        public DelegateCommand SaveCommand { get; set; }
        public DelegateCommand CleanCommand { get; set; }
        public DelegateCommand LoadCommand { get; set; }

        public MainPageViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            Title = "Main Page";

            SaveCommand = new DelegateCommand(async () =>
            {
                IFolder rootFolder = FileSystem.Current.LocalStorage;
                IFolder folder = await rootFolder.CreateFolderAsync("MySubFolder",
                    CreationCollisionOption.OpenIfExists);
                IFile file = await folder.CreateFileAsync("answer.txt",
                    CreationCollisionOption.ReplaceExisting);
                await file.WriteAllTextAsync(MyEntry);
            });
            CleanCommand = new DelegateCommand(() =>
            {
                MyEntry = "";
            });
            LoadCommand = new DelegateCommand(async () =>
            {
                IFolder rootFolder = FileSystem.Current.LocalStorage;
                IFolder folder = await rootFolder.CreateFolderAsync("MySubFolder",
                    CreationCollisionOption.OpenIfExists);
                IFile file = await folder.GetFileAsync("answer.txt");
                MyEntry = await file.ReadAllTextAsync();
            });
        }
    }
}

修正 Android 專案,進行 UserDialogs 的初始化

在這個文件中,並沒有提到需要在原生平台做任何初始化的工作,因此,我們也就不任何原生專案的修正。

進行測試

最後,設定預設起始專案為 Android 專案,並且選擇適當的模擬器或者實體手機,開始進行測試。
Acr.UserDialogs 執行結果

Xamarin.Forms / .NET Standard 體驗之旅 2 : 使用 Acr.UserDialogs 元件

由於 Prism Template Pack 已經開始支援創建出使用 .NET Standard 的共用類別庫專案,在接下來的幾篇文章,我將會針對在開發 Xamarin.Forms 專案的時候,會使用到不同需求功能的 NuGet 套件,進行測試與說明。
首先,我先針對在進行 Xamarin.Forms 專案開發時候,必備擴充 NuGet 套件 Acr.UserDialogs 進行測試,當然,在使用任何套件之前,強烈建議一定要先觀看官方的使用說明文件,因為,大部分的 Xamarin.Forms 擴充套件,都須做些適度的初始化設定工作。

測試範例專案原始碼

這篇文章中的測試範例專案原始碼,您可以從這裡取得

安裝最新的 Prism Template Pack

首先,請先確認您有安裝或者更新到最新的 Prism Template Pack 這個 Visual Studio 擴充功能,您可以點選 Visual Studio 2017 功能表的 [工具] > [擴充功能與更新] 選項,看到底下 [擴充功能與更新] 對話視窗,確認有安裝這個擴充 Prism Template Pack 功能。
今天有更新到 2.0.7 版本,所以,我們將會使用今天更新的最新 Prism Template Pack 擴充功能套件。
Prism Template Pack 2.0.7

開始建立專案

請點選功能表 [檔案] > [新增] > [專案],此時,您會看到底下的 [新增專案] 對話視窗。
我們點選 Prism Template Pack 提供的 Xamarin.Forms 專用的專案樣板,請點選 [已安裝] > [Visual C#] > [Prism] > [Prism Blank App (Xamarin.Forms)]。
接著在名稱欄位輸入該專案名稱後,點選 [確定] 按鈕,以建立此練習專案。
.NET Standard Xamarin.Forms Project
然後,在 [PRISM PROJEC WIZAD] 對話窗中,選擇您要跨平台的作業系統,容器 (Container) 這裡,我個人喜歡與習慣使用 Prism,您可以選擇您自己要用的容器,最後,點選 [CREATE PROJECT] 按鈕。
.NET Standard Xamarin.Forms Project

安裝 Acr.UserDialogs NuGet 套件

在這裡,請使用滑鼠右建,點選剛剛建立好的方案節點,選擇 [管理方案的 NuGet 套件] 項目。
在 [瀏覽] 標籤頁次上,輸入 Acr.UserDialogs 這個關鍵字,搜尋出這個套件。
從下圖中,我們看到搜尋出兩個 Acr.UserDialogs 相關套件,我們點選第一個,並且在右方區域,勾選 [NETStdUserDialogs] 這個 .NET Standard 專案(您可以不用勾選原生專案)
.NET Standard Xamarin.Forms Project
我們可以查看到這個 Acr.UserDialogs 套件,已經有支援 .NET Standard,也就是說,原則上,您所使用的 NuGet 套件,最好是能夠有支援 .NET Sandard 平台,使用上較不會遇到一些問題,若該套件還是僅支援 PCL ,這裡還是建議您先建立一個測試專案,測試在 .NET Standard 環境下使用是否有遇到任何問題。
.NET Standard Xamarin.Forms Project
當我們點選 [安裝] 按鈕之後,會看到 Visual Studio 會提示您這樣會安裝那些相依性的套件。
.NET Standard Xamarin.Forms Project

修正 View / ViewModel 開始使用 Acr.UserDialogs

安裝好套件之後,讓我們打開 MainPage.xaml 檔案,修改XAML內容。
這裡,我們僅在 StackLayout 版片配置內,加入一個按鈕項目,並且設定 Command 屬性,要綁定 ViewModel 內類型為 DelegateCommand 的物件 LoadCommand
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NETStdUserDialogs.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Button Text="Load" Command="{Binding LoadCommand}"/>
    </StackLayout>

</ContentPage>
接著我們打開 MainPageViewModel.cs 檔案,修正 ViewModel 的商業邏輯程式碼。
我們透過了 UserDialogs.Instance 這個物件,取得現在可用的 UserDialogs 物件,並且要顯示出 Loading 這個對話窗,我們會暫停兩秒鐘之後,這個對話窗便會消失掉。
namespace NETStdUserDialogs.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public DelegateCommand LoadCommand { get; set; }
        public MainPageViewModel(INavigationService navigationService) 
            : base (navigationService)
        {
            Title = "Main Page";
            LoadCommand = new DelegateCommand(async () =>
            {
                using (var dlg = UserDialogs.Instance.Loading("Test Progress"))
                {
                    await Task.Delay(2000);
                }
            });
        }
    }
}

修正 Android 專案,進行 UserDialogs 的初始化

如同前面強調的,使用 Xamarin.Forms 第三方套件的時候,務必要觀看使用說明,所以在 Acr.UserDialogs網頁中,有提到,我們需要在 Android 專案內進行初始化設定。
在 Android 專案內,找到 MainActivity.cs 檔案,打開這個檔案。
請在 [OnCreate] 方法內,加入這行 UserDialogs.Init(this); 敘述
protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);

    UserDialogs.Init(this);

    global::Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App(new AndroidInitializer()));
}

進行測試

最後,設定預設起始專案為 Android 專案,並且選擇適當的模擬器或者實體手機,開始進行測試。
使用 Acr.UserDialogs 相關對話窗的好處就是,如同底下測試結果,您會看到的是,這些對話窗將會是全螢幕顯示的。
Acr.UserDialogs 執行結果 Acr.UserDialogs 執行結果