2024年1月30日 星期二

.NET 8 MAUI 修正 SplashScreen 啟動顯示畫面 與 Icon 圖示 和應用程式名稱

.NET 8 MAUI 修正 SplashScreen 啟動顯示畫面 與 Icon 圖示 和應用程式名稱

當在進行 Android 和 iOS App 開發的時候,若採用的是 .NET MAUI 開發框架來進行開發,在建置完成並且執行後,在手機端將會看到的第一個畫面將會是 Splash screen ,這是應用程式啟動時顯示的第一個畫面,主要用途如下:

  • 提供視覺上的吸引力:Splash screen 可以使用圖片、動畫或文字等方式,來吸引使用者的注意力,並留下良好的第一印象。
  • 隱藏應用程式啟動過程:應用程式啟動時,需要完成許多初始化工作,例如載入資源、初始化元件等。Splash screen 可以顯示在這些工作完成之前,讓使用者在等待時不會感到無聊。
  • 傳達應用程式資訊:Splash screen 可以用來顯示應用程式的名稱、標誌或其他資訊,讓使用者快速了解應用程式的內容。

在 Android 中,Splash screen 可以使用 AndroidManifest.xml 檔案中的 android:splashScreen 屬性來指定。在 iOS 中,Splash screen 可以使用 Info.plist 檔案中的 UILaunchStoryboardName 屬性來指定。

不過,當在 .NET MAUI 中進行開發時,Splash screen 的設定方式與上述的方式有所不同,因為這些複雜與繁瑣的設定程序,都已經大幅度的簡化了,本文將會說明如何在 .NET MAUI 中設定 Splash screen。

不過,當在進行 Splash screen 需求設計的時候,需要特別關注一些事項,以下是一些 Splash screen 的設計注意事項:

  • Splash screen 的顯示時間不宜過長:Splash screen 的顯示時間過長,會讓使用者感到不耐煩。一般來說,Splash screen 的顯示時間應在 2 到 5 秒之間。
  • Splash screen 的圖片或動畫應與應用程式本身相符:Splash screen 應與應用程式的風格相一致,以營造一致的使用者體驗。
  • Splash screen 應使用高效能的圖片格式:Splash screen 使用的圖片格式應盡量小巧,以節省記憶體和電量。

以下是一些 Splash screen 的設計範例:

  • 使用圖片:圖片是 Splash screen 最常見的設計方式。圖片可以使用應用程式的標誌、主題圖片或其他相關圖片。
  • 使用動畫:動畫可以讓 Splash screen 更加生動有趣。動畫可以使用靜態圖片或影片來製作。
  • 使用文字:文字可以用來傳達應用程式的資訊,例如名稱、標誌或版本號碼。

在實際應用中,Splash screen 的設計可以根據應用程式的具體需求來定制。

還有另外兩個議題,那就是應用程式的名稱和 Icon 圖示,因為當一個 App 佈署到手機上時,手機上的應用程式列表中,會顯示應用程式的名稱和 Icon 圖示,如何在 .NET MAUI 中設定應用程式的名稱和 Icon 圖示,也是一個需要關注的議題。

建立 .NET 8 MAUI 專案

  • 打開 Visual Studio 2022 IDE 應用程式
  • 從 [Visual Studio 2022] 對話窗中,點選右下方的 [建立新的專案] 按鈕
  • 在 [建立新專案] 對話窗右半部
    • 切換 [所有語言 (L)] 下拉選單控制項為 [C#]
    • 切換 [所有專案類型 (T)] 下拉選單控制項為 [MAUI]
  • 在中間的專案範本清單中,找到並且點選 [.NET MAUI 應用程式] 專案範本選項

    此專案可用於建立適用於 iOS、Android、Mac Catalyst、Tizen 和 WinUI 的 .NET MAUI 應用程式。

  • 點選右下角的 [下一步] 按鈕
  • 在 [設定新的專案] 對話窗
  • 找到 [專案名稱] 欄位,輸入 MA06 作為專案名稱
  • 在剛剛輸入的 [專案名稱] 欄位下方,確認沒有勾選 [將解決方案與專案至於相同目錄中] 這個檢查盒控制項
  • 點選右下角的 [下一步] 按鈕
  • 現在將會看到 [其他資訊] 對話窗
  • 在 [架構] 欄位中,請選擇最新的開發框架,這裡選擇的 [架構] 是 : .NET 8.0 (長期支援)
  • 請點選右下角的 [建立] 按鈕

稍微等候一下,這個主控台專案將會建立完成

安裝要用到的 NuGet 開發套件

因為開發此專案時會用到這些 NuGet 套件,請依照底下說明,將需要用到的 NuGet 套件安裝起來。

安裝 CommunityToolkit.Mvvm 套件

CommunityToolkit.Mvvm 是微軟官方提供的 MVVM 套件,提供了一些 MVVM 開發常用的功能,例如:ObservableObject、ObservableProperty、RelayCommand 等等,這些功能在 WPF、UWP、Xamarin.Forms 都可以使用,而且在 .NET 8 MAUI 也可以使用。

請依照底下說明操作步驟,將這個套件安裝到專案內

  • 滑鼠右擊 [方案總管] 視窗內的 [專案節點] 下方的 [相依性] 節點
  • 從彈出功能表清單中,點選 [管理 NuGet 套件] 這個功能選項清單
  • 此時,將會看到 [NuGet: MA06] 視窗
  • 切換此視窗的標籤頁次到名稱為 [瀏覽] 這個標籤頁次
  • 在左上方找到一個搜尋文字輸入盒,在此輸入 CommunityToolkit.Mvvm
  • 稍待一會,將會在下方看到這個套件被搜尋出來
  • 點選 [CommunityToolkit.Mvvm] 套件名稱
  • 在視窗右方,將會看到該套件詳細說明的內容,其中,右上方有的 [安裝] 按鈕
  • 點選這個 [安裝] 按鈕,將這個套件安裝到專案內

.NET MAUI 應用程式預設的 Splash screen、Icon 圖示和應用程式名稱

請切換到 Android 平台下來進行執行此專案,執行後,將會看到預設的 Splash screen、Icon 圖示和應用程式名稱

一旦應用程式佈署到手機上,手機上的應用程式列表中,將會顯示應用程式的名稱和 Icon 圖示,在這裡將會看到有個藍紫色的圖示,在該圖示上有個 .NET 白色字體文字,而應用程式的名稱,則是預設為該專案名稱,也就是 MA06 這個名稱。

而當應用程式啟動時,將會看到預設的 Splash screen,這個 Splash screen 會顯示一個藍紫色的圖示,並且在該圖示上有個 .NET 白色字體文字。

另外一個在開發新的 .NET MAUI 專案時,會遇到的問題,就是該開發專案的 套件名稱(在 Android 平台下的稱呼)或應用程式識別碼(在 iOS 平台下的稱呼)要如何修改。

對於 Android 的套件名稱和 iOS 的應用程式識別碼都是用來唯一識別一個應用程式。它們在應用程式開發和部署過程中都起著重要作用。

在 Android 中,套件名稱是一個字串,由字母、數字和連字符組成。它必須是唯一的,不能與其他應用程式的套件名稱重複。套件名稱主要用於以下目的:

  • 在 Android 應用程式商店中識別應用程式。
  • 在 Android 系統中安裝和卸載應用程式。
  • 在 Android 應用程式之間進行通信。

在 iOS 中,應用程式識別碼是一個字串,由字母、數字和連字符組成。它必須是唯一的,不能與其他應用程式的應用程式識別碼重複。應用程式識別碼主要用於以下目的:

  • 在 App Store 中識別應用程式。
  • 在 iOS 系統中安裝和卸載應用程式。
  • 在 iOS 應用程式之間進行通信。

以下是一些套件名稱或應用程式識別碼的具體用途:

  • 在應用程式商店中,套件名稱或應用程式識別碼用來顯示應用程式的名稱和圖示。
  • 在應用程式安裝時,套件名稱或應用程式識別碼用來識別應用程式並將其安裝到正確的位置。
  • 在應用程式卸載時,套件名稱或應用程式識別碼用來識別應用程式並將其卸載。
  • 在應用程式之間進行通信時,套件名稱或應用程式識別碼用來識別應用程式並建立安全的連接。

在實際應用中,套件名稱或應用程式識別碼應盡量簡潔明瞭,並能與應用程式的名稱或主題相符。

.NET MAUI 開發框架也把這些複雜與繁瑣的設定程序,都已經大幅度的簡化了,若要查看 Android 平台下的套件名稱設定是甚麼內容,首先需要先建置這個 .NET MAUI 專案,使用檔案總管來開啟該路徑 [專案名稱\obj\Debug\net8.0-android],一旦切換到這個目錄下,將會看到有個 [AndroidManifest.xml] 檔案,請使用文字編輯器來開啟並檢視這個檔案內容,如下圖所示:

在最上方的 [manifest] 標籤內,將會看到有個 [package] 屬性,這個屬性值就是 Android 平台下的套件名稱,在這裡的範例中,將會是 [com.companyname.ma06] ;這個套件名稱是由 Visual Studio 2022 IDE 自動產生的,而且這個套件名稱是唯一的,不會與其他應用程式的套件名稱重複。

.NET MAUI 應用程式的 Splash screen

對於 .NET MAUI 的 Splash screen ,將會是透過一個 SVG 檔案來設計,而這個 SVG 檔案將會是一個可以顯示出 NET 白色文字的向量圖片檔案。

在方案總管中,展開資料夾 [MA06] > [Resources] > [Splash]

點選這個 [splash.svg] 檔案

為了要簡化練習,因此,可以從網路上隨機找一個 SVG 檔案。

由於 SVG 檔案的內容就是一群 XML 文字內容,因此使用文字編輯器打開剛剛下載的 SVG 檔案,並且將這個 SVG 檔案的內容複製到剪貼簿中,接著,將會回到 Visual Studio 2022 IDE 應用程式中,找到 [Splash] 資料夾,並且點選 [splash.svg] 這個 SVG 檔案,接著,把剪貼簿的全部內容替換掉這個 SVG 檔案的內容。

現在可以來使用 Figma 工具,檢視與預覽這個 SVG 檔案,下圖將會是透過 Figma 看到的預覽畫面:

現在要來調整當 .NET MAUI App 啟動之後,要顯示的 Splash screen ,在這裡將會需要將背景顏色做些調整成為墨綠色,接著,將 Splash screen 上的圖示換成為一個圖片,並且希望能夠指定這台汽車的顏色。

為了要完成這樣的需求,可以透過底下的步驟來進行修正

使用滑鼠雙擊這個專案節點,將會看到 [MA06.csproj] 這個設定檔案出現在螢幕上,對於這個檔案,也是一個 XML 檔案內容

找到 [MauiSplashScreen] 這個標籤,其內容預設如下:

<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

將這個標籤修正成為底下內容

<MauiSplashScreen Include="Resources\Splash\splash.svg" TintColor="#ebe544" Color="#548059" BaseSize="128,128" />

這裡將會宣告這個 .NET MAUI 的 Splash screen 的圖片顏色將會修正成為 [TintColor] 這裡所指定的色碼,也就是 黃色,這代表了將會顯示一部黃色車子出現在 Splash screen 上,而對於 [Color] 這個屬性,將會宣告這個 Splash screen 的背景顏色為 墨綠色。

底下將會是執行這個 .NET MAUI App 的 Splash screen 的畫面

.NET MAUI 應用程式的 Icon 圖示

在 .NET MAUI 框架中,對於 App Icon 將會使用兩個 SVG 檔案來設計,對於 [appicon.svg] 這個 SVG 檔案,本身就是一個矩形區塊,其中這個矩形將會具有藍紫色,也就是說,整個 App Icon 將會形成為藍紫色底色畫面;另外一個 SVG 檔案則為 [appiconfg.svg] ,對於這個 SVG 檔案將會是顯示在 App Icon 中間區域的圖片,在 .NET MAUI 框架下所建立的專案,這個 SVG 檔案將會是一個可以顯示出 NET 白色文字的向量圖片檔案。

底下將會是一個 .NET MAUI 應用程式的 App Icon 範例,這個 App Icon 將會是一個藍紫色底色畫面,並且在中間區域顯示出 NET 白色文字,如下圖所示:

首先來了解如何修正 .NET MAUI 應用程式的 App Icon ,在這裡將會需要將背景顏色做些調整成為淡綠色,接著,將 App Icon 上的 NET 字樣移除,最後,將 Splash screen 上的圖示換成為一個圖片。

在方案總管中,展開資料夾 [MA06] > [Resources] > [AppIcon]

在 [AppIcon] 資料夾中,找到並且點選 [appicon.svg] 這個 SVG 檔案,接著,將會看到這個 SVG 檔案的內容,如下圖所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect x="0" y="0" width="456" height="456" fill="#512BD4" />
</svg>

這個 SVG 檔案的內容是一個矩形,並且矩形的顏色是藍紫色,接著,將這個矩形的顏色改成為淡綠色,如下圖所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect x="0" y="0" width="456" height="456" fill="#adf7ae" />
</svg>

在此將會找到 [fill] 這個屬性,將原先的 [#512BD4] 色碼,修改成為 [#adf7ae],這樣就完成了 App Icon 的背景顏色修正工作

接下來,可以自行設計出要顯示在 App Icon 畫面上的圖形,不過,為了展示方便,將會從網路上隨機找到一個 SVG 圖片檔案,並且將這個新的 SVG 檔案內容 (對於 SVG 圖形檔案而言,該檔案的內容就是一群 XML 文字內容) 使用任何種類的文字編輯器打開,並且將這個 SVG 檔案的內容複製到剪貼簿中,接著,將會回到 Visual Studio 2022 IDE 應用程式中,找到 [AppIcon] 資料夾,並且點選 [appiconfg.svg] 這個 SVG 檔案,接著,將會看到這個 SVG 檔案的內容,如下圖所示:

現在可以來使用 Figma 工具,檢視與預覽這兩個 SVG 檔案,下圖將會是透過 Figma 看到的預覽畫面:

若實際執行這個專案,將會看到 App Icon 的畫面如下圖所示:

.NET MAUI 應用程式的 應用程式名稱與套件名稱

之前有完成了這個 App Icon 圖片的修正,最後,要來修正 .NET MAUI App 的應用程式名稱的修正,這樣使用者便可以在行動裝置上看到這個 App 的實際名稱。

同樣的,使用滑鼠雙擊專案節點,也就是 [MA06] 這個節點

現在可以看到這個 .NET MAUI 專案的 XML 設定內容

找到 [ApplicationTitle] 這個標籤,其內容如下

<!-- Display name -->
<ApplicationTitle>MA06</ApplicationTitle>

將 [MA06] 這個文字,修改成為 [我的 App],底下將會是完成的 XML 內容

<!-- Display name -->
<ApplicationTitle>我的 App</ApplicationTitle>

現在要來修正該應用程式的套件名稱,搜尋並且找到 [ApplicationId] 這個標籤,其內容如下

<!-- App Identifier -->
<ApplicationId>com.companyname.ma06</ApplicationId>

將 [com.companyname.ma06] 這個文字,修改成為 [com.vulcan.minicar],底下將會是完成的 XML 內容

<!-- App Identifier -->
<ApplicationId>com.vulcan.minicar</ApplicationId>

完成後,可以重新建置並且執行這個專案,接著,將會看到行動裝置桌面上看到這個 .NET MAUI App 的應用程式名稱與套件名稱已經完成修正

 





2024年1月26日 星期五

.NET 8 MAUI 使用客製化 MAUI 專案範本來進行開發

.NET 8 MAUI 使用客製化 MAUI 專案範本來進行開發

當要進行 .NET MAUI 專案開發時,通常會使用 Visual Studio 提供的預設專案範本來建立專案,這裡將會有兩種做法,一種是使用 Visual Studio 2022 來建立專案,另一種是使用 .NET CLI 來建立專案。

  • 使用 Visual Studio 2022 來建立專案

    • 開啟 Visual Studio 2022 程式

    • 點選右下角的 建立新的專案

    • 當出現 [建立新的專案] 視窗時,在該對話窗中間上方的 [所有語言 (L)] 下拉式選單中,選擇 C#

    • 在對話窗最上方的右側的 [所有專案類型 (T)] 下拉式選單中,選擇 MAUI

    • 現在可以在這個對話窗中,看到 [.NET MAUI 應用程式] 的範本,對於該範本的描述為:此專案可用於建立適用於 iOS、Android、Mac Catalyst、Tizen和 Win UI 的 .NET MAUI 應用程式

    • 如便可以建立起一個 .NET MAUI 的開發專案,畫面如下所示

  • 若要使用 .NET CLI 來建立專案

    • 請在命令提示字元視窗下,輸入下列指令來建立專案
dotnet new maui -o FirstMaui

不論是透過 GUI 或者 CLI 的方式來建立起來的專案,這些預設範本並不會包含 MVVM 的相關套件與相關的資料夾等等,因此當每次要建立一個 .NET MAUI 專案之後,就需要開始進行一下重複性的工作,現在,可以透過 Vulcan.Maui.Template 這個客製化的專案範本來建立 .NET MAUI 專案,這樣就可以省去後續繁複的開發時間。

現在來檢視使用預設 .NET MAUI 專案範本所建立起來的專案樣貌

這裡將會使用 Visual Studio 2022 來開啟剛剛建立的專案,從方案總管中可以看到,這裡僅有兩個預設的 [Platforms] 與 [Resources] 資料夾,這兩個資料夾是 .NET MAUI 專案的必要資料夾。

對於 .NET MAUI 的程式進入點程式碼,將會用到 [MauiProgram.cs] / [App.xaml] / [AppShell.xaml] / [MainPage.xaml] 這四個檔案,這些檔案都是預設的範本檔案,這裡僅列出 [MauiProgram.cs] 的程式碼,如下所示

using Microsoft.Extensions.Logging;

namespace FirstMaui
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });

#if DEBUG
    		builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
    }
}

安裝 Vulcan.Maui.Template 專案範本

  • 首先,需要開啟命令提示字元視窗
  • 接著輸入下列指令來查詢目前已經安裝的專案範本
dotnet new list

  • 若發現到已經有安裝 [Vulcan.Maui.Template] 專案範本,可以著輸入下列指令來移除 Vulcan.Maui.Template 專案範本
dotnet new uninstall Vulcan.Maui.Template
dotnet new install Vulcan.Maui.Template

底下是安裝完成的畫面

開始使用 Vulcan.Maui.Template 專案範本

  • 想要使用 [Vulcan.Maui.Template] 專案範本來建立 .NET MAUI 專案,可以透過 CLI 操作方式,輸入下列指令來建立專案
c:
cd c:\temp
dotnet new Vulcan-Maui -o c:\Temp\MA12
  • 底下為操作過程的畫面

  • 對於使用 CLI 方式建立的專案,其檔案結構與內容如下所示

  • 若想要使用 GUI 方式來建立專案,可以開啟 Visual Studio 2022 應用程式

  • 在 Visual Studio 2022 對話視窗中,點選右下角的 建立新的專案

  • 當出現 [建立新的專案] 對話視窗

  • 在該對話窗中間上方的 [所有語言 (L)] 下拉式選單中,選擇 C#

  • 在對話窗最上方的右側的 [所有專案類型 (T)] 下拉式選單中,選擇 MAUI

  • 現在可以在這個對話窗中,看到 [Vulcan Template .NET MAUI (Vulcan)] 的範本,對於該範本的描述為:此專案可用於建立適用於 iOS、Android、Mac Catalyst、Tizen和 Win UI 的 .NET MAUI 應用程式,如下圖所示

  • 點選 [Vulcan Template .NET MAUI (Vulcan)] 的範本,接著點選 [下一步(N)] 按鈕

  • 現在將會看到 [設定新的專案] 對話視窗

  • 在 [專案名稱] 文字方塊中,輸入 MA12

  • 點選螢幕右下方的 [建立] 按鈕 建立新的專案

  • 稍微等候一下,專案就會建立完成

檢視 Vulcan.Maui.Template 專案範本

現在使用 Visual Studio 2022 來打開剛剛建立的專案,從方案總管中可以看到,這裡有許多的資料夾,這些資料夾都是 .NET MAUI 專案的必要資料夾,這些資料夾的用途如下所示

  • [Views] 資料夾:用來放置所有的頁面,每一個頁面都是一個 .xaml 檔案,例如:[MainPage.xaml] / [AboutPage.xaml] / [SettingsPage.xaml] 等等
  • [ViewModels] 資料夾:用來放置所有的 ViewModel,每一個 ViewModel 都是一個 .cs 檔案,例如:[MainPageViewModel.cs] / [AboutPageViewModel.cs] / [SettingsPageViewModel.cs] 等等
  • [Services] 資料夾:用來放置所有的服務類別,每一個服務類別都是一個 .cs 檔案,例如:[IAppInfoService.cs] / [AppInfoService.cs] 等等
  • [Models] 資料夾:用來放置所有的資料模型類別,每一個資料模型類別都是一個 .cs 檔案,例如:[MessageModel.cs] / [ProductModel.cs] 等等
  • [Helpers] 資料夾:用來放置所有的輔助類別,每一個輔助類別都是一個 .cs 檔案,例如:[MagicValueHelper.cs] / [ApiHelper.cs] 等等
  • [Events] 資料夾:用來放置所有的事件類別,每一個事件類別都是一個 .cs 檔案,例如:[MyValueChangedMessage.cs] 等等

使用滑鼠雙擊這個 .NET MAUI 專案節點,就可以看到專案的內容,如下圖所示

這表示了這個專案除了原先 .NET MAUI 專案範本會用到的專案之外,還多了一些額外的套件,這些額外的套件都是為了讓開發者可以更快速的進行開發,這些額外的套件如下所示

  • [CommunityToolkit.Mvvm] 套件:這是一個社群開發的 MVVM 套件,透過原始碼產生器來生成在 MVVM 設計模式下會用到的額外程式碼,如此,讓整體 ViewModel 的原始碼看起來更加簡潔,並且可以讓開發者專注在 ViewModel 的商業邏輯上,而不是在繁瑣的程式碼上;另外一個好處將會是,可以大幅提升整體開發的速度與品質。
  • [CommunityToolkit.Maui] 套件:這是一個社群開發的 .NET MAUI 套件,這個套件提供了許多 .NET MAUI 專案開發時會用到的額外功能,這些功能都是在 .NET MAUI 專案開發時會用到的功能,透過這個套件,可以讓開發者更加快速的進行開發。
  • [Newtonsoft.Json] 套件:這是一個 JSON 處理的套件,這個套件可以讓開發者更加快速的進行 JSON 資料的序列化與反序列化,這個套件在 .NET MAUI 專案開發時會用到的功能。

MVVM 設計慣例與新增新的 View / ViewModel

在 .NET MAUI 專案開發時,通常會使用 MVVM 設計模式來進行開發,這裡將會介紹一下 MVVM 設計模式的慣例,以及如何新增新的 View / ViewModel。

在這個專案內,已經預設建立兩個資料夾,分別是 [Views] 與 [ViewModels] 資料夾,任何頁面的 .xaml 檔案都需要放置在 [Views] 資料夾內,而任何 ViewModel 的 .cs 檔案都需要放置在 [ViewModels] 資料夾內,這是一個 MVVM 設計模式的慣例。

另外,預設 .NET MAUI 專案範本所建立專案的 [MainPage.xaml] 這個頁面,將會搬移到 [Views] 資料夾,當然,在這裡將也會建立該頁面會用到的 ViewModel,也就是這個 [MainPageViewModel.cs] 檔案,這個檔案將會存在於 [ViewModels] 資料夾內。

這裡還有兩個要符合 MVVM 設計模式所做的調整,那就是在頁面的 Code Behind 後置碼建構式內,自動注入 ViewModel 物件到頁面內,並且將這個 ViewModel 物件到這個頁面的 [BindingContext] 物件內。另外,還有修正 [MauiProgram.cs] 這個檔案,在這裡需要加入 View 與 ViewModel 的對應關係,也就是要將 View 與 ViewModel 註冊到 DI 容器內。

通常來說,會使用底下這種方式來進行調整

builder.Services.AddTransient<MainPage>();
builder.Services.AddTransient<MainPageViewModel>();

不過,在這個專案範本中,已經有安裝了 [CommunityToolkit.Maui] 套件,這個套件提供了一個 [AddTransientWithShellRoute] 擴充方法,可以使用單一表示式來進行 View & ViewModel 對於 DI 容器的註冊與也會對 Shell 的 Route 進行註冊,這樣就可以省去一些重複性的工作。因此,在這個專案範本中,將不會使用上述的兩個敘述來進行註冊,而是使用底下的程式碼來進行註冊。

builder.Services.AddTransientWithShellRoute<MainPage, MainPageViewModel>(MagicValueHelper.MainPage);

在 [MainPageViewModel] 類別中,將會使用 [ObservableObject] 類別來實作 INotifyPropertyChanged 介面,這個類別是 [CommunityToolkit.Mvvm] 套件所提供的類別,這個類別可以讓開發者更加快速的進行開發。

由於在 .NET MAUI 專案中選擇與採用了 MVVM 設計模式,所以,當有需要增加一個新的頁面,就需要在這個專案的 [Views] 資料夾內新增一個 [頁面名稱Page.xaml] 檔案,並且也需要在 [ViewModels] 資料夾內新增一個 [頁面名稱PageViewModel.cs] 檔案,這兩個檔案的頁面名稱必須要相同,只有副檔名不同,這是一個 MVVM 設計模式的慣例。

如同上面的說明對於新建立的 View 的頁面 .xaml 檔案,需要在其後置碼 Code Behind 中,使用建構式注入方式,注入該新頁面會用到的 ViewModel 物件,並且指派給這個新頁面內的 [BindingContext] 屬性;對於 ViewModel 的類別 .cs 檔案,需要讓這個類別繼承 [ObservableObject] 類別,並且在該類別使用 [partial] 修飾詞。

對於這樣繁瑣冗長程序,在這個專案範本中,將會提供另外一個命令來解決此一問題,這個命令將會使用 [dotnet new] 來進行執行,這個命令的格式如下所示

dotnet new MVVMItem --namespace MA12 --view-name MyFirst

其中,對於 --namespace 需要傳入這個專案的組件的主要命名空間,在這裡的範例,將會為 MA12

另外,對於 --view-name 需要指定這次新頁面的名稱,不過,在這裡並不需要附加 [Page] 文字到所傳入的引數後,這個命令會依據 MVVM 設計慣例準則,自動加入 [Page] 這個文字

操作過如說明如下:

  • 滑鼠右擊專案節點

  • 從彈出功能表中選擇最下方的 [在終端機開啟] 功能表選項

  • 將這個命令 dotnet new MVVMItem --namespace MA12 --view-name MyFirst 輸入到終端機視窗內,在 Visual Studio 內看到的視窗名稱為 [開發人員 PowerShell],並且執行該命令

  • 一旦執行完成之後,將會出現 範本「Vulcan Maui MVVM View and View Model」已成功建立。 訊息,表示已經成功在 [Views] 與 [ViewModels] 資料夾內建立好了頁面 XAML 檔案與頁面 ViewModel 的類別檔案。

  • 現在可以觀察這個專案的 [Views] 與 [ViewModels] 資料夾內,已經有了新建立的頁面 XAML 檔案與頁面 ViewModel 的類別檔案,如下圖所示

  • [MyFirstPage.xaml] 檔案內容

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:MA12.ViewModels"
             xmlns:helpers="clr-namespace:MauiApp1.Helpers"
             Title="Page Title"
             x:Class="MA12.Views.MyFirstPage"
             x:DataType="viewModels:MyFirstPageViewModel">

  <Grid>
  </Grid>

</ContentPage>
  • [MyFirstPage.xaml.cs] 檔案內容
using MA12.ViewModels;

namespace MA12.Views;

public partial class MyFirstPage : ContentPage
{
    public MyFirstPage(MyFirstPageViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = viewModel;
    }
}
  • [MyFirstPageViewModel.cs] 檔案內容
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MA12.ViewModels;

public partial class MyFirstPageViewModel : ObservableObject
{
    #region Field Member
    #endregion

    #region Property Member
    #endregion

    #region Constructor
    public MyFirstPageViewModel()
    {
    }
    #endregion

    #region Method Member
    #region Command Method
    #endregion

    #region Navigation Event
    #endregion

    #region Other Method
    #endregion
    #endregion
}
  • 註冊剛剛建立的頁面與 ViewModel 到 DI 容器內
    • 在專案根目錄找到並且打開 [MauiProgram.cs] 檔案
    • 加入這行敘述 builder.Services.AddTransientWithShellRoute<MyFirstPage, MyFirstPageViewModel>(nameof(MyFirstPage));
    • 不過,對於這個方法要傳入的引數,建議使用 [MagicValueHelper] 類別內的靜態欄位來進行傳入,這樣可以避免打錯字的問題,例如:builder.Services.AddTransientWithShellRoute<MyFirstPage, MyFirstPageViewModel>(MagicValueHelper.MyFirstPage);
  • 底下將會是 [MagicValueHelper] 修正後的內容
namespace MA12.Helpers;

public class MagicValueHelper
{
    public const string FontName = "materialdesignicons";
    public const string MainPage = nameof(MainPage);
    public const string MyFirstPage = nameof(MyFirstPage);
}

其他補充說明

在使用這個專案範本所建立的專案中,對於 [Services] 資料夾將會用於設計該專案會用到的不同服務用途,在這裡將有提供一個服務的類別,其名稱為 [CounterService],這個 [CounterService] 服務類別將會在 [MauiProgram] 類別中註冊到 DI 容器內,因此,在這個專案的任何 ViewModel 內,都可以使用建構式注入的方式來進行注入 [CounterService] 這個服務物件。

namespace MA12.Services;

public class CounterService
{
    public string Get(int id) => $"訊息內容 : {id}";
}

對於 [Models] 資料夾,將是 MVVM Model-View-ViewModel 設計模式的資料模型資料夾,相關資料模型定義的類別,都將會儲存在這個資料夾內,在這專案範本所建立的專案中,將會有個 [MyMessage] 資料模型類別儲存在 [Models] 資料夾內,這個類別將會用於接下來的訊息傳遞(或稱之為事件聚合器設計模式)之用。

namespace MA12.Models;

public class MyMessage
{
    public int Counter { get; set; }
}

在 [Events] 資料夾內,將會有一個 [MyValueChangedMessage] 類別,這個類別將會用於接下來的訊息傳遞(或稱之為事件聚合器設計模式)之用。這是一個具有鬆散耦合的訊息傳遞設計模式,是由 [CommunityToolkit.Mvvm] 套件所提供,在這個專案範本中將會展示出這個設計用法;在進行 .NET MAUI App 開發過程中,這是一項很重要的技術,因為可以提供不同頁面間的 ViewModel 可以進行訊息或者資料交換之用。

using CommunityToolkit.Mvvm.Messaging.Messages;
using MA12.Models;

namespace MA12.Events;

public class MyValueChangedMessage : ValueChangedMessage<MyMessage>
{
    public MyValueChangedMessage(MyMessage myMessage) : base(myMessage)
    {
    }
}

在 MainPageViewModel 將會展示出訂閱與發佈訊息的做法。

在建構式內,使用底下程式碼來訂閱 [MyValueChangedMessage] 這個事件,一旦有其他程式碼發布 Publish 這個 [MyValueChangedMessage] 訊息,這裡所訂閱的委派方法,將會被觸發執行。

WeakReferenceMessenger.Default
    .Register<MyValueChangedMessage>(this, (r, m) =>
{

    MessagerText = counterService.Get(m.Value.Counter);
});

而在同樣的類別內,對於可用於命令綁定的 [CounterClicked] 方法內,將會使用底下用法,送出這樣的訊息出去

WeakReferenceMessenger.Default
    .Send(new MyValueChangedMessage(new Models.MyMessage()
    {
        Counter = Count
    }));

最後在這個專案內,將會有內建一個 [Google Material Design Icon] 字體檔案 (materialdesignicons-webfont.ttf),可以用於顯示出向量品質的圖示在螢幕上,這將會透過 [MauiProgram.cs] 檔案內的 fonts.AddFont("materialdesignicons-webfont.ttf", MagicValueHelper.FontName); 敘述來加入到 .NET MAUI 專案內。

因此在 [Helpers] 資料夾內,會有一個 [IconFont] 類別,將這些圖示的對應代碼,可以使用文字符號來定義,讓整體程式碼更具有可閱讀性。例如,若想要顯示 [帳號] 這樣的符號,可以直接使用 [IconFont.Account],其定義如下

public const string Account = "\U000f0004";

更多的可用圖示與對應名稱,可以透過 Webfont - Material Design Icons 網頁來來查看到