XAML in Xamarin.Forms 基礎篇 電子書

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

Xamarin.Forms 快速入門 電子書

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

特別說明

2019/11/06

Xamarin.Forms 快速上手 與 XAML 使用教學 雙修電子書

Xamarin.Forms 快速上手 與 XAML 使用教學 雙修電子書

更多關於 Xamarin.Forms 開發技術文章,可以參考 這裡

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

關於 Xamarin.Forms 快速上手

這是一本帶領 Xamarin.Forms 新手開發者,可以透過書中介紹的各種知識、開發技能,配合練習專案實作,快速地學會使用 Xamarin.Forms 這個 UI Toolkit 來進行跨平台的行動應用裝置之應用程式開發工作。
Xamarin.Forms 快速上手

這本書能提供什麼

在這本書裡面,將會提供 16 章的內容,分別是
  • 開發前的安裝、設定準備工作(共有三章)
    對於 Xamarin.Forms 開發新手,第一個學習卡關將會是如何安裝與設定一個可以進行 Xamarin.Forms 的開發環境;在這個部分將會詳細說明如何安裝與設定 Visual Studio 2019 ,使其可以順利的進行 Xamarin.Forms 的開發工作。
  • 使用 C# 程式語言來直接開發 Xamarin.Forms App
    說明如何僅使用 C# 程式語言,就可以開發出 Xamarin.Forms 的應用程式的開發過程。
  • 使用 XAML 標記宣告語言來開發 Xamarin.Forms App
    說明使用 XAML 宣告標記語言來進行頁面畫面的內容宣告,相關的商業邏輯則是使用 程式碼後置 Code Behind 的方式來開發。
  • 資料綁定 Data Binding
    資料綁定 Data Binding是在 Xamarin.Forms 開發上,最為重要的技術,對於資料綁定的類型共有三種,這裡將會針對一般資料物件類型的綁定設計方式來說明如何使用。
  • 更多資料綁定的用法
    這裡將會繼續介紹更多關於資料綁定的不同使用方式。
  • 數值轉換器 Value Converter
    對於資料綁定的設計方法下,數值轉換器的應用扮演者相當重要的角色,透過設計不同的數值轉換器類別可以設計出許多可重複使用的商業邏輯,並且輕鬆地將不同型別的綁定目標與綁定來源屬性串接在一起。
  • 命令綁定 Command Binding
    命令綁定是資料綁定的第二種類型,透過命令綁定可以不再需要使用以往需要透過事件訂閱的設計方式,與在 程式碼後置 區塊來進行相關商業邏輯的程式碼設計工作,全部都轉移到綁定來源的類別物件上。
  • 事件轉命令行為 Event to Command Behavior
    Xamarin.Forms 並不是所有的檢視項目都有提供可綁定的命令屬性,但是一定會有提供事件觸發的設計方式,在這裡將會使用 Xamarin.Forms 的一個核心技術 行為 Behaviors,將需要訂閱的事件與命令綁定在一起,這使得當事件被觸發的時候,可以執行所綁定的命令內的委派方法。
  • 手勢操作 Gesture Recognizer
    在 Xamarin.Forms 內提供可以與使用者互動的項目不多,按鈕是其中一個,不過, Xamarin.Forms 提供了手勢辨識器功能,可以在讓何檢視項目上,宣告不同的手勢操作行為,當發生了這個手勢操作行為,將會觸發所指定的命令,例如,得知使用者點選了一個圖片 UI 控制項。
  • MVVM Model-View-ViewModel 設計模式
    Xamarin.Forms 可以搭配 MVVM 的設計模式,讓 UI 視覺設計與呈現邏輯程式碼與商業邏輯程式碼分隔開來,這樣可以有助於程式開發流程、進行單元測試,因為,這解除了視覺控制項與程式碼之間的緊密耦合關係。
  • 內建導航服務
    開發行動應用程式最為重要的設計工作,那就是能夠在不同的頁面之間進行切換,在這裡會先進行 Xamarin.Forms 預設提供的導航服務功能進行介紹,並且了解到更多設計上的問題,可能需要進一步的解決。
  • 導航服務之封裝設計
    為了要解決 Xamarin.Forms 預設的導航服務的不足,已經可以在檢視模型中進行各種頁面導航操作,在這裡將會設計一個延伸導航服務類別,解決相關問題,讓開發過程更加的順暢。
  • 相依服務 Dependency Service
    Xamarin.Forms 是個 UI 開發工具,它把 UI 設計抽象化了,並且可以讓使用 Xamarin.Forms 設計的 UI 畫面可以在不同平台下來顯示出來,可是,當需要某些功能一定需要透過原生 SDK API 才能夠運作的需求,並且取得原生 SDK API 的執行結果,這個時候就可以透過 Xamarin.Forms 提供的相依服務來滿足這樣的工作。
  • 訊息中心 MessagingCenter
    訊息中心是一種 發行-訂閱 模式,其中對於 發行者 這個角色可以在不知道任何 訂閱者 的情況下傳送訊息。 同樣地,訂閱者 也可以在不知道任何 發行者 的情況下訂閱特定訊息。透過這樣的特行,可以讓 Xamarin.Forms 的程式順利地執行原生平台下的 SDK API。

誰適合閱讀這本書

本書適合想要學會如何使用 Xamarin.Forms 工具來開發出跨平台的行動應用程式的開發者,這裡將會介紹各種 Xamarin.Forms 核心與應用開發技術與技巧,並且帶領大家了解到進階的開發技能,如:檢視模型定位器,延伸導航服務等。透過學習這些開發技術,將會有助於進行各種 Xamarin.Forms 應用程式開發能力的提升。
不過,讀者本身應該要具備 .NET / C# 的開發經驗與程式寫作技能,並且要有使用過 Visual Studio 2019 開發經驗。
這本書的範例專案將會是在 Windows 10 作業系統下,使用 Visual Studio 2019 開發工具開發出來的,由於使用 Xamarin.Forms 開發出來的專案可以在 Android / iOS / UWP 平台下執行,若想要體驗開發出來的專案且在 iOS 模擬器環境下執行效果,讀者需要額外準備一台 Mac 電腦,並且在這台電腦上需要安裝 Xcode 與 Visual Studio for Mac 開發工具。

如何使用本書

在書中每個章節都設計了一個練習專案,透過逐步說明的方式來帶領讀者來了解到 Xamarin.Forms 專案是如何進行開發的,了解到為什麼需要使用這樣的開發方式與和其他設計方式差異。
本書中的所有講解範例專案都會放在 Github 上,您可以透過 Github 的 Xamarin-Forms-Quick-Start 來取得這些講解範例專案,並且鼓勵大家可以到這個 Xamarin-Forms-Quick-Start Repository 頁面,在螢幕的右上方,點選 Start 按鈕給予鼓勵,如同下圖箭頭所指向地方。

關於 XAML in Xamarin.Forms 基礎篇

XAML in Xamarin.Forms 基礎篇

這本書能提供什麼

在這本書裡面,將會設計 7 大部分
  • 開發前的安裝、設定準備工作
    對於 Xamarin.Forms 開發新手,第一個學習卡關將會是如何安裝與設定一個可以進行 Xamarin.Forms 的開發環境;在這個部分將會詳細說明如何安裝與設定 Visual Studio 2017 ,使其可以順利的進行 Xamarin.Forms 的開發工作,並且也會介紹一個學習 XAML 宣告式標記語言的輔助工具,設計時期預覽工具 大金剛 Gorilla Player 與 執行時期預覽設計工具 LiveXAML,對於如何安裝與使用進行說明。
  • 基本概念
    這個部分將會介紹您學習 XAML 語言必須要先瞭解的各種基本知識與觀念,讓您初步綜覽在學習 XAML 語言比須具備的基本技能。
  • XAML 共用屬性
    我們將說明 XAML 提供的各種類別與其階層關係,這些類別將會被所使用的各種頁面、版面配置、檢視項目所繼承,因此,您可以從這些頁面、版面配置、檢視項目中,使用基底類別所提供的各種屬性、方法與事件。
    這些共用的基底類別包含了: 可綁定物件 BindableObject,項目 Element,視覺項目 VisualElement,頁面 Page,檢視 View,版面配置 Layout
  • 各種不同頁面
    頁面是在 Xamarin.Forms 開發上,最為重要的使用者介面項目,當使用者在開啟此應用程式,第一個畫面內容就是一個頁面;原則上,我們進行 Xamarin.Forms 專案開發,就是要設計出各種不同頁面,並且根據應用程式設計需求,將這些頁面串接起來,提供使用者來操作這些頁面上設計的內容。
    Xamarin.Forms 內提供了這些頁面可供選擇:內容頁面、導航頁面、主從階層頁面、標籤頁面、旋轉木馬頁面。
  • 各種不同版面配置
    我們要把各種 XAML 提供的視覺項目,定位在螢幕上的指定地方,並且可以根據螢幕的大小、解析度、密度來自動調整要顯示出我們所希望的結果,畢竟,要根據不同螢幕的大小、解析度、密度來設計出各種不同的 XAML 文件,這是相當麻煩的,因此,我們將會透過 XAML 中的版面配置來幫助我們自動做到這些事情。
    在 Xamarin.Forms 有提供眾多的版面配置,每個版面配置可以針對不同的設計情境來使用,這包括了:框架、內容檢視、堆疊方式版面配置、格線、捲動檢視、絕對版面配置、鄉對版面配置、彈性方塊版面配置。
  • 各種不同檢視
    檢視是要提供與使用者互動的使用者介面,例如,讓使用者輸入文字、顯示出各種圖片、文字、請使用者選擇指定的日期與時間等等,在這部分將會帶領大家了解這些檢視的功能與使用方式。
  • 各種資料綁定語法
    最後,會針對這本書上各種範例中有用到的資料綁定使用方式,進行完整的歸納與整理,讓您清楚了解如何在 XAML 中正確的使用資料綁定,來幫助您進行各種情境的 Xamarin.Fomrs 應用程式開發。

誰適合閱讀這本書

本書適合想要學會各種 XAML 開發技巧的開發者,將會提供基本 XAML 知識與觀念,不同 XAML 項目的使用與應用的介紹,當然,您還是需要擁有基本的 .NET C# 程式語言的開發經驗。

如何使用本書

在書中除了會提供各種學習 XAML 宣告式標記語言的內容,並搭配不同的應用程式範例進行介紹,從書中的第三部份,將會說明這段內容的講解範例是如何製作出來,希望讀者根據書中的說明步驟,搭配講解內容,逐一自我在電腦前面進行演練,可快速增加學習 XAML 的經驗值。
本書中的所有講解範例專案都會放在 Github 上,您可以透過 Github 的 XAMLInXamarin 來取得這些講解範例專案,並且鼓勵大家可以到這個 XAMLInXamarin Repository 頁面,在螢幕的右上方,點選 Start 按鈕給予鼓勵,如同下圖箭頭所指向地方。
在 XAMLInXamarin 上建立一個 Issue 操作示意圖




2019/11/04

Xamarin.Forms 客製化導航服務 Navigation Service 與檢視模型定位器 ViewModel Locator

Xamarin.Forms 客製化導航服務 Navigation Service 與檢視模型定位器 ViewModel Locator

該文件的專案原始碼可以透過 GitHub 來取得

設定 MyGet 的可用套件來源

現在,已經把 檢視模型定位器 ViewModel Locator 與 客製化的導航服務推送到 MyGet 站台上,因此,可以透過底下方式是,來安裝這個 NuGet 套件
  • 點選 Visual Studio 2019 功能表 [工具] > [選項]
  • 當 [選項] 對話出現的時候,從左邊清單選項找到 [NuGet 套件管理員]
  • 在左方 [名稱] 欄位中輸入適當的名字,這裡將會輸入 上課練習或者體驗專案會使用到的常用功能
  • 在左方 [來源] 欄位中輸入 [上課練習或者體驗專案會使用到的常用功能](https://www.myget.org/F/course-lab/api/v3/index.json) 這個 URL
  • 點選 [更新] 按鈕
    )
  • 記得要確認 [可用套件來源] 選項中,剛剛建立的套件來源項目有被勾選
現在可以建立一個練習測試用的專案

建立測試用的專案

  • 請啟動 Visual Studio 2019
  • 在啟動後的對話窗內,選擇右下方的 [建立新的專案] 選項
  • 當顯示出 [建立新專案] 對話窗,請在中間上方的文字輸入盒內,輸入 Xamarin 這個關鍵字
  • 此時將會在中間清單區域,找到 [行動應用程式 (Xamarin.Forms)] 這個選項,請點選這個項目
  • 在 [設定新的專案] 對話窗內,請在專案名稱欄位內,輸入 CustNaviService
  • 請點選右下方的 [建立] 按鈕
  • 現在將會跳出一個 [New Cross Platform App - CustNaviService] 對話窗
  • 請選擇 選取範本 區域內的 [空白] 項目
  • 在下方的 [平台] 區域,請記得勾選 Android , iOS , Windows (UWP) 這三個檢查盒 Checkbox
  • 點選右下方的 [OK] 按鈕
  • 開始建立 Xamarin.Forms 開發方案

加入 檢視模型定位器 ViewModel Locator 與 客製化的導航服務 套件

  • 滑鼠右擊 CustNaviService 核心專案節點
  • 選擇管理 NuGet 套件選項
  • 當 [NuGet: CustNaviService] 視窗 出現後,請在右上方的 [套件來源] 下拉選單中,選擇 [上課練習或者體驗專案會使用到的常用功能] 這個項目
  • 在 [NuGet: CustNaviService] 視窗中,點選瀏覽頁次
    )
  • 現在將會看到這裡擁有兩個 NuGet 套件,請選擇 [Vulcan.Courses.XamarinForms] 這個套件
    )
  • 點選 [安裝] 按鈕,安裝這個套件到核心專案內

使用 MVVM 命名慣例來建立所需要用到的方案資料夾

  • 滑鼠右擊 CustNaviService 核心專案節點
  • 選擇 [加入] > [新增資料夾] 選項
  • 請輸入 ViewModels 這個文字做為該資料夾的名稱
  • 滑鼠右擊 CustNaviService 核心專案節點
  • 選擇 [加入] > [新增資料夾] 選項
  • 請輸入 Views 這個文字做為該資料夾的名稱

建立導航頁面 NavigationPage 與導航抽屜頁面 MasterDetailPage

這裡需要先建立起這兩個頁面,因此,請在 [Views] 資料夾內,建立這兩種類型的頁面
在這裡將會建立一個名為 NaviPage 的導航頁面
在這裡將會建立一個名為 MDPage 的導航頁面

建立會用到的其他內容頁面 ContentPage 與 相對應的 檢視模型 ViewModel 類別

請在 [Views] 資料夾內,建立 HomePage AboutPage LoginPage 這三個頁面
請在 [ViewModels] 資料夾內,建立 HomePageViewModel AboutPageViewModel LoginPageViewModel MDPageViewModel MDPageMasterViewModel 這五個檢視模型類別
最後完成的結果如底下螢幕截圖
)

使用 檢視模型定位器 ViewModel Locator

想要使用這項服務,對於頁面 ( 檢視 ) 檔案 與 檢視模型 檔案,需要遵守底下的命名慣例
  • 對於 頁面 ( 檢視 View ) 的 XAML 文件檔案,需要建立在 Views 這個方案資料夾內
  • 每個頁面檔案名稱,最後需要使用 Page 作為結為,例如,這裡有建立一個 HomePage.xaml 這樣的 XAML 頁面文件檔案
接著,需要在每個頁面中,建立一個命名空間,這個命名空間要指向 服務定位器所在的 .NET 命名空間內 Namespace
在底下的 XAML 文件中,將會使用 xmlns 來宣告一個新的 viewmodelLocator 命名空間,其中, viewmodelLocator 稱之為 前置詞 prefix
有了這個前置詞,就可以使用 AutoWireViewModel 這個附加屬性,依據所規範的命名慣例,自動找出該頁面所匹配的檢視模型,當然,該檢視模型將會位於該專案的 ViewModel 方案資料夾內。
xmlns:viewmodelLocator="clr-namespace:Vulcan.Courses.XamarinForms.NaviServices;assembly=Vulcan.Courses.XamarinForms"
viewmodelLocator:ViewModelLocator.AutoWireViewModel="True"

使用 客製化導航服務

為了要能夠使用這裡所設計的 客製化導航服務,每個檢視模型 ViewModel 類別,需要繼承 ViewModelBase 這個基底類別,該類別是在之前所安裝的 NuGet 內所定義的。
另外,還需要在每個檢視模型類別的建構函式內,呼叫基底類別的建構函式,這裡需要傳入一個導航服務物件。不過,這裡的導航服務物件將會位於此 Xamarin.Forms 專案內的程式進入點,也就是在 App 這個類別內有宣告,稍後,將會交代如何做這一的設計。
從底下的範例程式碼可以看出,透過 Application.Current 這個靜態變數,取得了一個 App 型別的物件,就可以取出 NavigationService 這個變數物件值。
public class AboutPageViewModel : ViewModelBase
{
    public AboutPageViewModel() : base((Application.Current as App).NavigationService)
    {
    }
}
現在,請打開 App.xaml.cs 這個檔案節點,在 App 這個類別內,加入一個公開屬性 public INaviService NavigationService { get; set; } ,接著在該 App 類別的建構函式內,建立 NavigationService 這個物件,這裡使用了 NavigationService = new NaviService( () => { return Application.Current.MainPage as NaviPage; }, page => { return new NaviPage(page); }, () => { return (Application.Current.MainPage as MDPage)?.Detail as NaviPage; }, () => { return Application.Current.MainPage as MDPage; }, () => { return new MDPage(); });
對於 NaviService 的建構函式,將會需要傳遞五個委派方法,分別是要取得導航頁面的委派方法、產生一個新的導航頁面的委派方法、取得一個導航抽屜頁面+導航頁面的委派方法、取得一個導航抽屜的委派方法、產生一個導航抽屜的委派方法;所以,請將上面的所列的表示式,放到這個 App 類別內的建構函式內即可。
在這個 App 類別內的建構函式,將會看到如何使用客製化導航服務的頁面導航的程式設計程式碼,NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.Absolute); ;這裡將會需要使用 NavigateToAsync 這個泛型方法,在泛型型別參數內,指定要導航過去的檢視模型型別名稱即可,而在這個方法內,可以指定一個導航模式,也就是 NavigateMode 這裡列舉型別。這裡使用到了 NavigateMode.Absolute 這個列舉值,表示將會使用沒有導航頁面的模式,切換到指定的內容頁面上。
public partial class App : Application
{
    public INaviService NavigationService { get; set; }
    public App()
    {
        InitializeComponent();

        NavigationService = new NaviService(
            () => { return Application.Current.MainPage as NaviPage; },
            page => { return new NaviPage(page); },
            () => { return (Application.Current.MainPage as MDPage)?.Detail as NaviPage; },
            () => { return Application.Current.MainPage as MDPage; },
            () => { return new MDPage(); });

        //MainPage = new MainPage();

        NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.Absolute);
    }

    protected override void OnStart()
    {
        // Handle when your app starts
    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

其他的頁面導航操作

若想要使用具有導航頁面的模式的頁面,可以使用 NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.Absolute); 這樣的用法
而要使用具有導航抽屜的頁面模式(一定會使用到導航頁面),可以使用 NavigationService.NavigateToAsync<HomePageViewModel>(NavigateMode.Master);
若在導航抽屜頁面下,想要切換到僅有導航頁面(沒有抽屜)的模式下,可以使用 NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.RestartRelative);

實際執行結果

底下是應用程式一起動要顯示的頁面,沒有任何導航頁面與導航抽屜頁面,這裡是使用 NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.Absolute);
)
當在上面畫面點選了 [登入] 按鈕,出現底下畫面(有導航抽屜),這裡使用的是 NavigationService.NavigateToAsync<HomePageViewModel>(NavigateMode.Master);
)
在 [首頁] 頁面下方,點選 [關於] 按鈕,將會使用導航頁面功能,切換到關於頁面,這裡使用的是 NavigationService.NavigateToAsync<AboutPageViewModel>();
)
在關於頁面左上方,將會看到一個箭頭,這表示現在這個頁面在導航堆疊結構中,前面至少還有一個頁面,此時,點選左上方箭頭(或者點選下方實體回上頁按鈕),便可以回到上一頁頁面。
)
在 [關於] 頁面內,從裝置外部左方往右滑動,將會看到導航抽屜出現,這裡的 Page 1 ~ Page 4 都會有建置功能,可以分批測試看看。
首先點選 Page 1,將會直接回到 [首頁] 頁面, 並且清空導航堆疊內的所有頁面,這裡使用的是 NavigationService.NavigateToAsync<HomePageViewModel>(NavigateMode.Master);
)
再度滑出導航抽屜,點選 Page 2,將會直接回到 [關於] 頁面, 並且清空導航堆疊內的所有頁面,這裡使用的是 NavigationService.NavigateToAsync<AboutPageViewModel>(NavigateMode.Master);
)
滑出導航抽屜,點選 Page 3,將會直接回到 [登入] 頁面,此時沒有導航抽屜頁面,也沒有導航頁面的存在,這裡使用的是 NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.Absolute);
)
請點選 [登入] 按鈕,進入到有導航抽屜頁面的首頁內,滑出導航抽屜,點選 Page 4,將進入到 [登入] 頁面,不過,此時沒有導航抽屜頁面,但卻有導航頁面的存在,這裡使用的是 NavigationService.NavigateToAsync<LoginPageViewModel>(NavigateMode.RestartRelative);
)







2019/09/04

升級到 VS2019 16.2.3 後,要執行 Xamarin.Android 專案,卻得到 System.IO.FileNotFoundException: 'Invalid Image' 錯誤訊息

升級到 VS2019 16.2.3 後,要執行 Xamarin.Android 專案,卻得到 System.IO.FileNotFoundException: 'Invalid Image' 錯誤訊息

最近這兩個月因為忙於 Xamarin.Forms 的授課,所以,一直沒有將上課用的 Surface Pro 4 電腦上的 Visual Studio 2019 軟體升級到最新版本,本來想等到 09/03 最後一天課程上完之後,再來進行 Visual Studio 2019 的升級工作,沒想到 09/03 當天授課的時候,卻發現到 Visual Studio 2019 無法打開,電腦上顯示需要我把 Visual Studio 進行升級,這是我最擔心的一件事情,因為,每次軟體有升級的時候,都會怕對於上課過程中有些影響(這也就是為什麼,當會進行類似 Xamarin.Forms 6 天這樣長時間的授課時候,通常不會把 Visual Studio 進行升級 ,一來擔心新功能的推出對於授課會有,二來擔心有些狀況僅會出現在新升級後的電腦,而學員的電腦上的 Visual Studio 卻沒有升級,造成不一致的問題;所以,在上課之前,我通常是僅會將作業系統進行更新到最新版本這樣的動作而已。
好的,那麼當天究竟發生了甚麼事情?當我將 Visual Studio 2019 升級到最新版本,也就是 16.2.3 版本,當我使用了 Prism Template Pack 建立起一個 Xamarin.Forms 的專案後,首先在 Visual Studio 2019 的錯誤視窗中,看到了底下的訊息。
警告        Skipping BlankApp2.Droid.Resource.Attribute.actionBarSize. Please check that your Nuget Package versions are compatible.    BlankApp2.Android
雖然該訊息僅是個警告訊息,不過,還是覺得怪怪的,緊接著開始進行 Xamarin.Android 的專案建置與執行的動作,不幸的是,此時在螢幕上顯示了 System.IO.FileNotFoundException Message=Invalid Image 這個錯誤訊息,如同底下螢幕截圖顯示的狀況。
這下慘了,課程僅進行到 30 分鐘,若無法建立一個空的 Xamarin.Forms for Prism 專案,那麼要如何繼續底下 6個小時的課程呢?(心裡有著 今日可以提早完課,下次再來的念頭)。
我還是先花了一些時間做了檢測,首先,看到在 Visual Studio 2019 輸出視窗中的最後一行,看到了 Assembly Loader probing location: '/storage/emulated/0/Android/data/com.companyname.appname/files/.__override__/Xamarin.Interactive.dll'. **System.IO.FileNotFoundException:** 'Invalid Image' 這樣的訊息,我想,這個訊息應該是上面對話窗所遇到的主要問題。
接下來的內容,是我回到家裡後,使用另外一台電腦上的 Visual Studio 2019,也把它升級到 16.2.3 版本,結果看到相同的問題,但是,當我不使用 Prism Template Pack 來產生一個 Prism Blank App (Xamarin.Forms) 的應用程式,而是使用 Visual Studio 2019 內建的 行動應用程式 (Xamarin.Forms) 專案範本,建立起一個空的 Xamarin.Forms 的專案,卻沒有發現到這個專案在建置與執行過程中,會出現上述的問題,一切都可以正常運作。
我針對 使用 Prism Template Pack 所產生的 Xamarin.Form 專案,打開 Xamarin Android 專案內的 MainActivity.cs 檔案,接著,在 OnCreate 方法內加入訂閱 AppDomain.CurrentDomain.UnhandledException 這個事件,看看是否能夠捕捉到任何可疑的例外異常錯誤資訊,並且在 int foo = 10; 這個敘述上設定一個中斷點,若執行的過程中可以停在剛剛設定的那行中斷點上,那麼,也許可以從 UnhandledExceptionEventArgs 這個參數中,看到一些端倪。
protected override void OnCreate(Bundle bundle)
{
    AppDomain.CurrentDomain.UnhandledException += (s, e) =>
    {
        // 這一行是要用於設定中斷點之用
        int foo = 10;
    };
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);

    global::Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App(new AndroidInitializer()));
}
當修正好了之後,再度執行這個專案,依然還是看到這個這個錯誤訊息,並且並沒有停留在剛剛設定的中斷點上,所以,這應該是這個專案尚未啟動到 MainActivity 的時候,就產生了問題。
現在回到 Xamarin.Forms 授課當天,那時,只好針對幾個設定項目進行測試,看看是否可以讓課程繼續進行下去,這個時候,只要使用 Prism Template Pack 建立的專案,可以正常建置、執行,那麼,當天的課程就可以繼續下去囉。
這裡是當天解決這個問題的其中一個做法
  • 首先打開 Xamarin.Android 專案的屬性設定視窗 (可以滑鼠右擊 Android 專案節點,選擇最後面的屬性項目,或者在 Android 專案內找到 Properties 節點,使用滑鼠雙擊這個節點)
  • 當 Android 屬性視窗出現之後,切換到 Android 選項 標籤頁次 Tabbed,且解除 使用 Fast Deployment (僅限偵錯模式) 這個選項)
注意,底下的螢幕截圖,是 使用 Fast Deployment (僅限偵錯模式) 這個選項被設定的狀態,請要解除該 Checkbox 的設定
現在,重新建置與執行這個專案,看看能否執行起來
喔喔,這樣的設定終於解除的當前危機,再度建立一個新的 Prism Black App 專案,看看是否會有同樣的效果,結果也是沒有問題。
另外一個解法則是剛剛測試出來的,不需要取消 使用 Fast Deployment (僅限偵錯模式) 這個選項設定,維持著 Fast Deployment 的設定,不過,在同一個標籤頁次下,也就是 Android 專案屬性視窗下的 Android 選項視窗中,往下捲動將會看到 正在連結 這個設定。
一開始使用 Prism Template Pack 建立起來的 Xamarin Android 專案中,其 正在連結 設定為 無 ,現在可以修正為 僅限 SDK 組譯碼 這個選項,我發現到可以維持在除錯模式下持續使用 Fast Deployment 的機制,也可以正常運作。