2024年5月10日 星期五

在Blazor使用Fluent UI元件-2

 作者:許薰尹  精誠資訊/恆逸教育訓練中心資深講師


Fluent UI 是 Microsoft 提供的一套 UI 框架,提供了許多預先設計好的元件,如按鈕、輸入方塊、下拉式選單等,讓開發者不需從無到有,可以快速地建立出具有一致性、豐富又美觀的使用者介面。

在本站《在Blazor使用Fluent UI元件 - 1》一文中介紹如何使用Fluent UI Blazor官方提供的專案範本來建立應用程式。在這一篇文章中,我們將介紹如何在現有的Blazor專案中,手動加入Fluent UI元件的功能。

建立Blazor專案


首先使用Visual Studio 2022開發工具建立一個Blazor專案開始,建立步驟如下:啟動Visual Studio 2022開發環境,從「開始」視窗選取「Create a new project」選項。從Visual Studio 2022開發工具的「Create a new project」對話盒中,選取 使用C# 語法的「Blazor Web App 」項目,然後按一下「Next」按鈕,請參考下圖所示:

圖 1:使用「Blazor Web App 」項目建立專案。


下一步,在「Configure your new project」視窗中,設定Blazor專案名稱與專案存放路徑,然後按下「Next」按鈕,請參考下圖所示:

圖 2:設定Blazor專案名稱與專案存放路徑。


下一步,在「Additional information」視窗中,設定「Target Framework」為「NET 8.0 (Long Term Support)」;將「Authentication Type」設為「None」;「Interactive render mode」選擇「Server」;「Interactivity location」設定為「Global」,然後勾選「Include sample pages」,然後按下「Create」按鈕,請參考下圖所示:




圖 3:設定「Target Framework」為「NET 8.0 (Long Term Support)」。



專案建立完成之後,從「Solution Explorer」視窗中可以看到專案的結構,請參考下圖所示:

圖 4:專案結構。


接下來讓我們了解一下Fluent UI Blazor 元件庫的手動安裝方法。

手動安裝NuGet 套件


若想要從頭開始在你的 Blazor 應用程式使用 Fluent UI Blazor 元件庫,第一步需要在Blazor 應用程式中安裝「Microsoft.FluentUI.Blazor」 NuGet 套件。您可以透過 IDE 內建的 NuGet 套件管理員進行安裝,步驟如下:

從「Solution Explorer」視窗 –> 專案名稱上方,按滑鼠右鍵,從快捷選單選擇「Manage NuGet Packages」項目。從對話盒「Browse」分頁上方文字方塊中,輸入查詢關鍵字找到「Microsoft.FluentUI.AspNetCore.Components」套件,請參考下圖所示:





圖 5:安裝「Microsoft.FluentUI.AspNetCore.Components」套件。



點選「Install」按鈕進行安裝。然後重複相同的步驟,安裝「Microsoft.FluentUI.AspNetCore.Components.Icons」套件,請參考下圖所示:

圖 6:安裝「Microsoft.FluentUI.AspNetCore.Components.Icons」套件。




重複相同的步驟,安裝「Microsoft.FluentUI.AspNetCore.Components.Emoji」套件,請參考下圖所示:

圖 7:安裝「Microsoft.FluentUI.AspNetCore.Components.Emoji」套件。



套件安裝完成後,專案檔案看起來如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Project Sdk = "Microsoft.NET.Sdk.Web">
 
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include = "Microsoft.FluentUI.AspNetCore.Components" Version = "4.6.1" />
    <PackageReference Include = "Microsoft.FluentUI.AspNetCore.Components.Emoji" Version = "4.6.0" />
    <PackageReference Include = "Microsoft.FluentUI.AspNetCore.Components.Icons" Version = "4.6.1" />
  </ItemGroup>
 
</Project>



安裝這些相關套件後,您就可以在應用程式中使用 Fluent UI Blazor 元件了。
註冊Fluent UI
下一步在「Program.cs」檔案,叫用「AddFluentUIComponents( )」方法將 Fluent UI 的元件註冊到 DI 容器中,請參考以下程式碼:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using FluentUIDataGrid.Components;
using Microsoft.FluentUI.AspNetCore.Components;
 
var builder = WebApplication.CreateBuilder( args );
 
// Add services to the container.
builder.Services.AddRazorComponents( )
    .AddInteractiveServerComponents( );
 
builder.Services.AddFluentUIComponents( );
 
var app = builder.Build( );
 
// Configure the HTTP request pipeline.
if ( !app.Environment.IsDevelopment( ) ) {
  app.UseExceptionHandler( "/Error", createScopeForErrors: true );
  // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
  app.UseHsts( );
}
 
app.UseHttpsRedirection( );
 
app.UseStaticFiles( );
app.UseAntiforgery( );
 
app.MapRazorComponents<App>( )
    .AddInteractiveServerRenderMode( );
 
app.Run( );



引用命名空間


修改「_Imports.razor」檔案,在 Blazor 應用中引入 Fluent UI 元件庫的命名空間。這樣在元件的程式碼中就可以直接使用該命名空間下的類別、結構、列舉等,而不需要寫出完整的命名空間路徑,請參考以下程式碼:

1
2
3
4
5
6
7
8
9
10
11
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using FluentUIDataGrid
@using FluentUIDataGrid.Components
@using Microsoft.FluentUI.AspNetCore.Components

 


設計元件


在專案中加入Razor元件,從「Solution Explorer」視窗 -「Pages」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「Razro Component」項目,請參考下圖所示:

圖 8:加入「Razro Component」項目。


在「Add New Item」視窗,指定元件名稱為「MyDataGridComponent.razor」後,按下「Add」按鈕,請參考下圖所示:

圖 9:指定元件名稱為「MyDataGridComponent.razor」。



在元件中加入以下程式碼,使用了一個名為「FluentDataGrid」的元件來顯示一個書籍列表。每一本書籍都有一個唯一的ID、標題(Title)、價格(Price)、出版日期(PublishDate)、庫存狀態(InStock)以及描述(Description)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<h3> MyDataGridComponent </h3>
 
<FluentDataGrid Items = "@books">
  <PropertyColumn Property = "@(b => b.Id)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.Title)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.Price)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.PublishDate)" Format = "yyyy-MM-dd" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.InStock)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.Description)" Sortable = "true" />
 
</FluentDataGrid>
 
@code {
  record Book( int Id, string? Title, int Price, DateTime PublishDate, bool InStock, string? Description );
 
  IQueryable<Book> books = new [ ]
   {
       new Book( 1, "Essential Programming Language", 250, new DateTime( 2022, 1, 2 ), true, "Essential Programming Language"),
       new Book( 2, "Telling Arts", 245, new DateTime( 2022, 4, 15 ), true, "Telling Arts"),
       new Book( 3, "Marvel", 150, new DateTime( 2022, 2, 21 ), true, "Marvel"),
       new Book( 4, "The Beauty of Cook", 450, new DateTime( 2022, 12, 2 ), true, "The Beauty of Cook"),
       new Book( 5, "The Art of Design", 300, new DateTime( 2022, 6, 10 ), true, "The Art of Design"),
       new Book( 6, "Science Fiction", 200, new DateTime( 2022, 8, 18 ), true, "Science Fiction"),
       new Book( 7, "History of Art", 180, new DateTime( 2022, 3, 25 ), true, "History of Art"),
       new Book( 8, "The Mystery Novel", 350, new DateTime( 2022, 9, 5 ), true, "The Mystery Novel"),
       new Book( 9, "Fantasy World", 280, new DateTime( 2022, 7, 12 ), true, "Fantasy World")
       }.AsQueryable( );
 
}


在「FluentDataGrid」元件中,使用了多個「PropertyColumn」子元件來定義每一直欄的內容。每個「PropertyColumn」都有一個「Property」屬性,該屬性使用了一個Lambda表達式來繫結到書籍物件的特定屬性。例如,@(b => b.Id)就是繫結到書籍的「Id」屬性。此外,每個「PropertyColumn」都設定了「Sortable = "true"」,表示該直欄可以進行排序。

在「@code」區塊中,定義了一個名為Book的記錄(record)類型,以及一個「IQueryable」類型的「books」變數。此變數初始化為一個包含多個Book物件的陣列,並使用「AsQueryable()」方法轉換為「IQueryable」。這樣做的目的是為了讓「FluentDataGrid」元件能夠對進行查詢和排序。



接下來修改「Home.razor」程式碼,加入「MyDataGridComponent」元件,參考以下範例程式碼:

 

1
2
3
4
5
@page "/"
@rendermode InteractiveServer
<PageTitle> Home </PageTitle>
 
<MyDataGridComponent> </MyDataGridComponent>


這個範例的執行結果,請參考下圖所示:

圖 10:使用「FluentDataGrid」元件執行結果


點選直欄上的標題就可以進行排序,請參考下圖所示:

圖 11:「FluentDataGrid」元件排序執行結果。

 

使用「TemplateColumn」客製化


若想要自訂「FluentDataGrid」元件每一個直欄要顯示的內容,可利用「TemplateColumn」客製化。修改上個範例的程式碼,在「FluentDataGrid」元件中定義了一個「TemplateColumn」直欄,內容包含一個圖片,用於顯示書籍的封面,參考以下範例程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<h3> MyDataGridComponent </h3>
 
<FluentDataGrid Items = "@books">
  <PropertyColumn Property = "@(b => b.Id)" Sortable = "true" />
  <TemplateColumn Tooltip = "true"
                  TooltipText = "@(b => b.Title + "的圖片")"
                  Align = "Align.Center"
                  SortBy = "@idSort"
                  Title = "Cover">
    <img class = "cover" src = "images\@(context.Id).png" alt = "@(context.Id + "的圖片")" />
  </TemplateColumn>
  <PropertyColumn Property = "@(b => b.Title)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.Price)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.PublishDate)" Format = "yyyy-MM-dd" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.InStock)" Sortable = "true" />
  <PropertyColumn Property = "@(b => b.Description)" Sortable = "true" />
</FluentDataGrid>
 
@code {
  record Book( int Id, string? Title, int Price, DateTime PublishDate, bool InStock, string? Description );
 
  IQueryable<Book> books = new [ ]
  {
    new Book( 1, "Essential Programming Language", 250, new DateTime( 2022, 1, 2 ), true, "Essential Programming Language"),
    new Book( 2, "Telling Arts", 245, new DateTime( 2022, 4, 15 ), true, "Telling Arts"),
    new Book( 3, "Marvel", 150, new DateTime( 2022, 2, 21 ), true, "Marvel"),
    new Book( 4, "The Beauty of Cook", 450, new DateTime( 2022, 12, 2 ), true, "The Beauty of Cook"),
    new Book( 5, "The Art of Design", 300, new DateTime( 2022, 6, 10 ), true, "The Art of Design"),
    new Book( 6, "Science Fiction", 200, new DateTime( 2022, 8, 18 ), true, "Science Fiction"),
    new Book( 7, "History of Art", 180, new DateTime( 2022, 3, 25 ), true, "History of Art"),
    new Book( 8, "The Mystery Novel", 350, new DateTime( 2022, 9, 5 ), true, "The Mystery Novel"),
    new Book( 9, "Fantasy World", 280, new DateTime( 2022, 7, 12 ), true, "Fantasy World")
  }.AsQueryable( );
 
  GridSort<Book> idSort = GridSort<Book>
        .ByDescending( x => x.Id );
 
 
}
 
<style>
  .cover {
    height: 100px;
    margin: auto;
  }
</style>




「TemplateColumn」元件的屬性說明如下:
 「Tooltip」屬性設定為「true」,表示當滑鼠移到該欄位上時,會顯示一個小提示。「TooltipText」屬性則是定義了提示的內容,它是一個Lambda表達式,會將書籍的標題和固定的文字"的圖片"組合成字串顯示。
 「Align」屬性設定為Align.Center,表示該直欄的內容會居中對齊。
 「SortBy」屬性繫結到了一個名為「idSort」的變數,該變數定義了如何對該直欄進行排序。在這個例子中,「idSort」是按照書籍的ID進行降冪排序。
 「Title」屬性設置為"Cover",這是直欄的標題。

在「TemplateColumn」元件的內部,定義了一個「img」項目來顯示圖片。「src」屬性的值是根據書籍的ID來決定的,圖片的路徑是「images」資料夾加上書籍的ID,並以「.png」結尾。「alt」屬性的值也是一個Lambda表達式,用於在圖片無法顯示時提供替代的文字說明。

這個範例的執行結果請參考下圖所示:

圖 12:使用「TemplateColumn」客製化。



👍學習推薦

l   【GPTGH】使用GitHub Copilot提高Coding生產力-程式設計AI詠唱

l   【UAC399】ASP.NET Core Web API/Minimal API微服務開發實務

l   【OPAI】使用Visual Studio 2022 開發Azure OpenAI應用程式

l   【UAC495】全面掌握ASP.NET Core Razor Page網站開發技巧

l   【UAC496】ASP.NET Core MVC網站開發從設計到實作Part 1

l   【UAC497】ASP.NET Core MVC網站開發從設計到實作Part 2

l   【UAC498】從設計到實作ASP.NET Core Blazor網站開發

l   【U2249】掌握Vue.JS漸進式前端框架開發技術

l   【UN398】.NET MAUI跨界先鋒從桌面到移動的全平台開發旅程

l   【UN492】.NET精粹的極致技術解密之旅



👉👉👉索取微軟網站開發技術系列 優惠訊息與課程資料


0 意見:

張貼留言