XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

2017/04/17

Xamarin.Forms 與 Azure Mobile App Lab 5

在 Azure 行動應用後端專案,新增差旅費用頁面需要用的資料表

為了要進行這個部分練習,需要建立一個新的SQL Database資料表,因此,我們需要啟用 Code First Migration 功能,來幫助我們依據專案內的資料模型,進行自動調整遠端資料庫內的綱要 (Schema) 內容。
  • 開啟您從 Azure Moible App 項目中下載的 XamarinAzureService 內的 XamarinAzureDay.sln Visual Studio 專案
    下圍呈現了這個 Visual Studio 方案/專案的結構
  • 按下 F5 ,在本地端執行這個專案
    您可以使用 PostMan 來檢查本地端執行與運作結果是否正常
  • 中斷除錯執行
  • 點選功能表 工具 > NuGet封裝管理員 > 套件管理員主控台
  • 在 套件管理員主控台 中輸入底下指令
Enable-Migrations
完成後,會出現底下訊息
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded migration '201702111723152_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.
Code First Migrations enabled for project XamarinAzureDayService.
  • 接著,執行底下指令
Add-Migration Initial
完成後,會出現底下訊息
Scaffolding migration 'Initial'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration Initial' again.
  • 打開資料夾 App_Start 底下的 Startup.MobileApp.cs 檔案
  • 在這個檔案最上方加入底下 using
using System.Data.Entity.Migrations;
using XamarinAzureDayService.Migrations;
  • 將這行程式碼註解起來 Database.SetInitializer(new XamarinAzureDayInitializer());
  • 在剛剛註解的程式碼後,加入底下程式碼
            var migrator = new DbMigrator(new Migrations.Configuration());
            migrator.Update();
  • 按下 F5 ,在本地端執行這個專案
    您可以使用 PostMan 來檢查本地端執行與運作結果是否正常
  • 中斷除錯執行

建立資料傳輸物件 (DTO) 類別

接下來,我們需要修改這個後端 API 專案,讓這個專案可以提供更多的功能。
  • 為了要開始產生一個我們自訂的資料表,我們需要定義資料表控制器, 設定資料表控制器需要三個步驟︰
這裡,我們需要定義一個差旅費用的申請紀錄表單,用來定義 SQL Database 內的資料表。
  • 請滑鼠右擊 DataObjects 資料夾,選擇 加入 > 類別
  • 在對話窗下方的 名稱 輸入 BusinessTripExpense
  • 點選 新增 按鈕
  • 請將剛剛產生的類別 BusinessTripExpense,修改成為如下程式碼:
    public class BusinessTripExpense : EntityData
    {
        public DateTime 出差日期 { get; set; }
        public string 類型 { get; set; }
        public string 項目名稱 { get; set; }
        public string 地點 { get; set; }
        public double 費用 { get; set; }
        public string 備註 { get; set; }
        public bool 國內外 { get; set; }
        public bool 是否有單據 { get; set; }
    }
若有找不到的類別或者命名空間,請點選燈泡來修正

EntityData 類別

每個要新增的資料表類別,需要繼承 EntityData 這個類別,這個類別的定義如下。
    public bool Deleted { get; set; }
您可以看到我們並不需要額外定義 Id 作為每筆紀錄的唯一紀錄欄位,因為在 EntityData 內已經幫我們加入進來了 (要實作出 ITableData 這個介面);而其他的欄位 CreatedAt / Deleted / UpdatedAt / Version 將會用於方便 Azure Mobile 服務進行使用 Entity Framework 工作處理之用。
    //
    // 摘要:
    //     An abstract implementation of the Microsoft.Azure.Mobile.Server.Tables.ITableData
    //     interface indicating how the system properties for a given table data model are
    //     to be serialized when communicating with clients when using Entity Framework
    //     for accessing the backend store. The uniform serialization of system properties
    //     ensures that the clients can process the system properties uniformly across platforms.
    //     Concrete entity framework models can derive from this base class in order to
    //     support the system properties.
    public abstract class EntityData : ITableData
    {
        protected EntityData();

        [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute]
        [Index(IsClustered = true)]
        [TableColumn(TableColumnType.CreatedAt)]
        public DateTimeOffset? CreatedAt { get; set; }
        [TableColumn(TableColumnType.Deleted)]
        public bool Deleted { get; set; }
        [System.ComponentModel.DataAnnotations.KeyAttribute]
        [TableColumn(TableColumnType.Id)]
        public string Id { get; set; }
        [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute]
        [TableColumn(TableColumnType.UpdatedAt)]
        public DateTimeOffset? UpdatedAt { get; set; }
        [TableColumn(TableColumnType.Version)]
        [System.ComponentModel.DataAnnotations.TimestampAttribute]
        public byte[] Version { get; set; }
    }

建立資料表控制器。

如果已安裝 Azure SDK,您現在可以建立範本資料表控制器,請進行底下操作

使用 Azure 行動應用程式資料表控制器

  • 滑鼠右擊 Controller 資料夾,選擇 加入 > 控制器
  • 在對話窗中,選擇 Azure 行動應用程式資料表控制器
  • 點選新增按鈕
  • 在出現 新增控制器 對話窗,請輸入或者選擇如下圖結果
    模型類別:您剛剛定義的 SQL 資料表型別,可用下拉選單來選擇
    資料內容類別:,也就是這個專案內繼承 DbContext 的類別,可用下拉選單來選擇
    控制器名稱:可以使用自動產生的名稱,注意,最後面一定要有 Controller
  • 點選 新增 按鈕,完成這個資料表控制器產生動作。
  • 底下為產生後的 BusinessTripExpenseController 資料控制器程式碼
    您可以看到,對於差旅費用資料表的基本 CRUD API 程式碼,都已經幫您自動產生好了
    這裡請特別注意,在使用 Azure Mobile App 的資料表控制項類別中,必須要繼承 TableController 這個類別,而不是要使用 ApiController 類別
    public class BusinessTripExpenseController : TableController<BusinessTripExpense>
    {
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);
            XamarinAzureDayContext context = new XamarinAzureDayContext();
            DomainManager = new EntityDomainManager<BusinessTripExpense>(context, Request);
        }

        // GET tables/BusinessTripExpense
        public IQueryable<BusinessTripExpense> GetAllBusinessTripExpense()
        {
            return Query(); 
        }

        // GET tables/BusinessTripExpense/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public SingleResult<BusinessTripExpense> GetBusinessTripExpense(string id)
        {
            return Lookup(id);
        }

        // PATCH tables/BusinessTripExpense/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task<BusinessTripExpense> PatchBusinessTripExpense(string id, Delta<BusinessTripExpense> patch)
        {
             return UpdateAsync(id, patch);
        }

        // POST tables/BusinessTripExpense
        public async Task<IHttpActionResult> PostBusinessTripExpense(BusinessTripExpense item)
        {
            BusinessTripExpense current = await InsertAsync(item);
            return CreatedAtRoute("Tables", new { id = current.Id }, current);
        }

        // DELETE tables/BusinessTripExpense/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task DeleteBusinessTripExpense(string id)
        {
             return DeleteAsync(id);
        }
    }

加入 Migration

  • 點選功能表 工具 > NuGet封裝管理員 > 套件管理員主控台
  • 在 套件管理員主控台 中輸入底下指令
Add-Migration BusinessTripExpense
  • 按下 F5 ,在本地端執行這個專案
    您可以使用 PostMan 來檢查本地端執行與運作結果是否正常
  • 中斷除錯執行

發佈到 Azure 雲端上

PostMan 測試資料

本地端

Azure

Header 資訊

Key : ZUMO-API-VERSION
Value : 2.0.0

這個練習範例專案,請參考

XamarinAzureService_Custom

Xamarin.Forms 與 Azure Mobile App Lab 4

下載 Xamarin.Forms 用戶端專案

  • 您可以接續上一個步驟繼續接下來的動作,或者,先回到 Azure 儀表板首頁,找到 xamarinazureday 行動 APP 圖示,點選這個圖示;接著,從 XamarinAzureDay App Service 刀鋒視窗中,點選 快速入門 > Xamarin.Forms
  • 現在,您應該可以看到如下圖的內容,,請在 3.設定您的用戶端應用程式 區塊來進行操作
    請點選 下載 按鈕,下載 Xamarin.Forms 專案檔案
  • 若您點選了 連接現有應用程式 則會出現底下內容,告訴您如何在您現有的專案中,加入 Microsoft.Azure.Mobile.Client 並且經建立適當程式碼,就可以存取您的 Azure Mobile App 後端服務了。

測試 Xamarin.Forms 專案

  • 在這裡需要實際執行與測試 Azure Mobile App 所提供的 Xamarin.Forms 專案
  • 請打開您剛剛下載的 Xamarin.Forms 專案,使用 Visual Studio 2015 打開 XamarinAzureDay.sln 檔案。
  • 滑鼠右擊 Android 原生專案 ( XamarinAzureDay.Droid ),選擇,設定為起始專案
  • 按下 F5 開始進行這個 Xamarin.Forms 專案偵測
  • 此時,您可以在電腦中的 Android 模擬器中,這個應用程式實際執行結果,如同看到底下畫面
  • 您也可以實際在 Item name 欄位中輸入代辦工作事項名稱,接著點選右方 + 按鈕,此時,這筆紀錄就會儲存到遠端 Azure SQL Server 上了

如何確認資料有寫到遠端 Azure SQL Server 上了

  • 在這裡,我們將會使用 PostMan 來做為展示說明,當然,您也可以在 C# 中實際使用這個方法來呼叫。
  • 首先,打開 XamarinAzureDay App Service 項目。
  • 在刀鋒視窗右上方,找到 URL ,將這個 URL 值複製下來
  • 打開您的 PostMan App
  • 請選擇 Get 方法,在網址列填入 http://xamarinazureday.azurewebsites.net/tables/todoitem
    其中, http://xamarinazureday.azurewebsites.net 是剛剛從 Azure 儀表板中複製下來的網址。
  • 在 Header 頁次中,輸入 Key 為 ZUMO-API-VERSION / value 為 2.0.0
  • 點選最右方的 Send 藍色按鈕,就可以查詢到這個代辦清單表格內的所有資料。

Xamarin.Forms 與 Azure Mobile App Lab 3

下載後端伺服器使用的 ASP.NET 專案與發佈到 Azure 上

  • 您可以接續上一個步驟繼續接下來的動作,或者,先回到 Azure 儀表板首頁,找到 xamarinazureday 行動 APP 圖示,點選這個圖示;接著,從 XamarinAzureDay App Service 刀鋒視窗中,點選 快速入門 > Xamarin.Forms
  • 現在,您應該可以看到如下圖的內容,請在 2.建立資料表 API 區塊來進行操作
    設定 後端語言 為 C#
    點選下載按鈕,下載後端專案原始碼

測試與佈署到 Azure 上

  • 在這裡,您可以打開這個 ASP.NET 的專案,建置並確認沒有問題發生
  • 滑鼠右擊專案 XamarinAzureDayService,選擇 發行
  • 在 發行 對話窗,在設定檔中點選 Microsoft Azure App Service
  • 在 App Service 對話窗中,選擇剛剛建立的 App Service 方案,也就是 DoggyXamarin > XamarinAzureDay
    +

  • 點選 `確定 按鈕
  • 在 連接 頁次,點選 驗證連接 按鈕
  • 若 驗證連接 成功,點選 發行 按鈕
  • 此時,您 Azure 上的後端 API 服務,將會有這個專案來取代。

Xamarin.Forms 與 Azure Mobile App Lab 2

建立 Azure 行動應用要用到的 SQL 資料庫

在這裡,我們將會使用剛剛建立的 XamarinAzureDay App Service 來進行設定要存取的後端資料庫。
  • 首先,開啟 Microsoft Azure 找到 XamarinAzureDay 行動App ,並且開啟它
  • 在 XamarinAzure 刀鋒視窗中,找到 快速入門 項目,點選這個 快速入門 > Xamarin.Forms
  • 在 Xamarin.Forms 快速入門 刀鋒視窗中,點選 連結資料庫 下方的區塊
  • 在 資料連接 刀鋒視窗中,點選 + 新增 按鈕
  • 在 新增資料連線 刀鋒視窗中,類型欄位,選擇 SQL Database
  • 點選 SQL Database 設定必要設定
  • 在 資料庫 刀鋒視窗中,點選 建立新的資料庫
  • 在 SQL Database 刀鋒視窗中,找到
    名稱欄位,請輸入 XamarinAzureDB
    定價層欄位,請選擇 B基本 (這種資料庫主機服務為:最多 2GB / 異地複寫 / 還原時間點 7 天 / 稽核,預設為 S0 標準方案)
    目標伺服器欄位,在這裡,我們心建立一個測試用的資料庫伺服器,使用設定參數如下:
    • 伺服器名稱:XamarinAzureSQLServer
    • 伺服器管理員登入:請在這裡填入您想要的 SQL Server 管理員帳號
    • 密碼:請在這裡填入該SQL Server管理員的密碼
    • 位置:東南亞
    • 允許 AZURE 服務存取此伺服器:請勾選這個項目
    • 點選 選取 按鈕
    再回到 SQL Database 刀鋒視窗後,點選該視窗下方的 選取 按鈕
  • 當回到 新增資料連線 刀鋒視窗中,點選 連接字串 下方區域
  • 在 連接字串 刀鋒視窗中,點選 確定 按鈕
  • 當回到 新增資料連線 刀鋒視窗中,點選 確定 按鈕
    這個時候,Azure 會開始建立 SQL Server 主機與資料庫,請稍後片刻。
  • SQL Server 與 資料庫建立完成之後,會看到如下畫面。

Xamarin.Forms 與 Azure Mobile App Lab 1

建立 Azure Mobile App

這裡有兩種方法可以建立 Azure Mobile App Service,若您對於 Azure Mobile App 不孰悉的話,建議您使用第二個作法。

使用 Web + 行動 > Moibl App 建立 Azure Mobile App

在這裡我們需要建立一個 Azure Mobile App Server來提供我們後端的資料存取服務。
  • 打開 Microsoft Azure 儀表板
  • 在 Microsoft Azure 儀表板頁面左上方,找到 + 新增 區域,點擊這個連結
  • 在 新增 刀鋒視窗中,選擇 Web + 行動
  • 在 Web + 行動 刀鋒視窗中,選擇 Mobile App
  • 在 Mobile App 刀鋒視窗中,依序輸入 應用程式名稱 / 訂戶名稱 / 資源群組 / App Service 方案/位置,下圖為這個練習所建立的 Mobile App 資訊。
    應用程式名稱 : XamarinAzureDay
    資源群組(新建): DoggyXamarin
    App Service 方案/ DoggyXamarinAsiaAppService / Southeast Asia
    定價層:F1免費
  • 在 Mobile App 刀鋒視窗下,點選 釘選到儀表板
  • 接著點 建立 按鈕,完成建立這個 Azure Mobile App 服務
  • 您需要等候一段時間,Azure 會進行部署相關服務到特定機器上。

使用 Mobile Apps Quickstart 建立 Azure Mobile App

在這裡,我們使用 Azure 提供的 Mobile App 快速入門 應用程式,來快速幫我們建立起這一個後端資料庫存取服務
  • 打開 Microsoft Azure 儀表板
  • 在 Microsoft Azure 儀表板頁面左上方,找到 + 新增 區域,點擊這個連結
  • 在 新增 刀鋒視窗中,請在搜尋文字輸入盒內(有 搜尋Marketplace 文字處),輸入 Mobile Apps
  • 請在 Everything 刀鋒視窗中,點選 Mobile Apps Quickstart 這個項目
  • 在 Mobile Apps Quickstart 刀鋒視窗中,請點選 建立 按鈕
    底下為這個刀鋒視窗中顯示的說明文字:
    Accelerate your mobile app development with this ready-to-use Mobile App todo sample. Azure Mobile Apps uses Azure App Service to provide a turnkey way to store structured data, authenticate users, and send push notifications. With native and cross-platform SDKs for iOS, Android, Windows, and JavaScript, as well as a powerful and flexible REST API, Azure Mobile Apps empowers you to build connected applications for any platform and deliver a consistent experience across devices.
    • Pre-configured for a basic SQLite database
    • Connect to on-premise or Azure-hosted SQL databases
    • Authenticate users via Azure Active Directory, Facebook, Google, Microsoft and Twitter
    • Push notifications via Apple, Google and Microsoft services
    • Gain insights with mobile analytics
    • Auto-scale to millions of devices
  • 在新出現的刀鋒視窗中,請依序填入底下欄位所需要的內容
    應用程式名稱 : XamarinAzureQuickstartDoggy
    (請依照您的需求,填入您想要的應用程式名稱)
    資源群組(使用現有項目): DoggyXamarin
    (您可以新建或者選擇使用現有項目)
    App Service 方案/ DoggyXamarinAsiaAppService / Southeast Asia
    定價層:F1免費
    (這裡可以依照您的需求來選取或定義)
    底下為這個練習範例所建立的 Mobile Apps Quickstart 資訊
  • 最後,請勾選 釘選到儀表板 ,並且點選 建立 按鈕
  • 您需要等候一段時間,Azure 會進行部署相關服務到特定機器上。
  • 當這個服務建立完成之後,會出現底下刀鋒視窗 XamarinAzureQuickstartDoggy / Mobile Apps Quickstart
    最上方中間的那個圖示 xamarinazurequickstart 行動App 就是這個後端服務設定入口點。

2017/04/16

我要使用 Code Behind or MVVM ?

以下為作者個人觀點,不同意者,請直接跳過。

  1. 首先,要選擇使用 MVVM or Code Behind 方式來開發,並沒有甚麼特別的準則,使用選擇適合您的開發方式來開發即可。

    (我個人儘量不去使用 Code Behind,是因為,我可以將這些商業邏輯,寫在 Service Layer & ViewModel 內,這些內容都會與 View 無關,方便做出許多的處理工作,例如:Unit Test、容易的將這些商業邏輯一道其他頁面中來共用、不同的 View 可以共用同一個 ViewModel、將 UI & Logical 徹底切割開 ==> 這點對我而言,相當的重要,因為,我可以很容易的找出問題底點與方便和容易維護我寫的程式碼與XAML)

  2. MVVM 有個主要的精神,那就是可以使用 Unit Test 的方式,來進行您的開發專案邏輯測試;這是因為,在 ViewModel 內,並沒有使用到任何 View 的內容,所以,您可以很容易地進行 Unit Test。

  3. 若您有使用過 Win Form 的專案開發,那麼,這樣的開發工具,就只有 Code Behind 的方式可以選擇,若您使用過 WPF 的專案開發,則兩種方式都可以。

  4. 若要在 Service Layer 使用到頁面導航,對話窗等許多功能,這些物件,儘可以在 Code Behind 內使用,因此,若您想要在 Service Layer 處理一些導航等相關工作,勢必需要做些其他處理,才能夠在 Service Layer 做到這些功能;當然,這樣的做法,會影響到 Unit Test 的執行。

  5. 使用 Code Behind 方式開發,每次都需要在 XAML 中宣告 x:Name 屬性,因此,有點花時間與麻煩,另外,在進行 XAML 與 Code Behind 專案維護的時候,會造成一些困擾(有用過的皆知到);另外,在某些情況下,若您僅僅使用 Code Behind 來處理這些問題,將會非常的棘手與麻煩。