提供您專業技能的最佳管道,IT企業主管唯一推薦

提供您專業技能的最佳管道,IT企業主管唯一推薦

2024年6月12日 星期三

在Blazor使用Fluent UI元件-5

作 者:恆逸資深講師 許薰尹

在本站《在Blazor使用Fluent UI元件 - 4》一文介紹如何在現有的Blazor專案中,手動加入Fluent UI元件 ,並使用「FluentDialog」元件設計確認刪除的對話盒。在這一篇文章中,我們將介紹延續這系列文章的情境,介紹該如何自訂對話盒,以便讓其它元件能夠重複使用這個對話盒。



設計MyDialog


首先讓我們使用元件來自訂對話盒,元件的程式碼可放在專案根目錄下的「Shared」資料夾。從「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「Shared」。

在「Shared」資料夾中加入Razor元件,從「Solution Explorer」視窗 -「Shared」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「Razro Component」項目,將元件名稱命為「MyDialog.razor」,然後在檔案中加入以下程式碼:


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
@using Microsoft.FluentUI.AspNetCore.Components
@implements IDialogContentComponent<FluentUIDataGrid.Models.Customer>
 
@* Header *@
<FluentDialogHeader ShowDismiss = "true">
  <FluentStack VerticalAlignment = "VerticalAlignment.Center">
    <FluentIcon Value = "@(new Icons.Regular.Size24.WindowApps())" />
    <FluentLabel Typo = "Typography.PaneHeader">
        @Dialog.Instance.Parameters.Title
    </FluentLabel>
  </FluentStack>
</FluentDialogHeader>
 
@* Footer *@
<FluentDialogFooter>
  <FluentButton Appearance = "Appearance.Accent" OnClick = "@DeleteAsync"> Delete </FluentButton>
  <FluentButton Appearance = "Appearance.Neutral" OnClick = "@CancelAsync"> Cancel </FluentButton>
</FluentDialogFooter>
 
@* Body *@
<FluentDialogBody>
  <FluentTextField @bind-Value = "@Content.CustomerId"> CustomerId: </FluentTextField>
  <FluentTextField @bind-Value = "@Content.CompanyName"> CompanyName: </FluentTextField>
  <FluentTextField @bind-Value = "@Content.ContactName"> ContactName: </FluentTextField>
</FluentDialogBody>
 
@code {
  [Parameter]
  public FluentUIDataGrid.Models.Customer Content { get; set; } = default!;
 
  [CascadingParameter]
  public FluentDialog Dialog { get; set; } = default!;
 
  private async Task DeleteAsync() {
    await Dialog.CloseAsync( Content );
  }
 
  private async Task CancelAsync() {
    await Dialog.CancelAsync( );
  }
}




分別說明如下,以下這兩行程式碼是在引入了必要的命名空間,並且實作了「IDialogContentComponent」介面,該介面的泛型參數是「FluentUIDataGrid.Models.Customer」:

1
2
@using Microsoft.FluentUI.AspNetCore.Components
@implements IDialogContentComponent<FluentUIDataGrid.Models.Customer>



以下程式碼建立了自訂對話盒的標題部分。「FluentDialogHeader」是對話盒的標題,「ShowDismiss」屬性設為「true」表示可以關閉對話盒。「FluentStack」是一個容器類型的元件,裡面包含了一個圖示(FluentIcon)和一個標籤(FluentLabel),這個標籤顯示的是對話盒的標題:

1
2
3
4
5
6
7
8
9
@* Header *@
<FluentDialogHeader ShowDismiss = "true">
  <FluentStack VerticalAlignment = "VerticalAlignment.Center">
    <FluentIcon Value = "@(new Icons.Regular.Size24.WindowApps())" />
    <FluentLabel Typo = "Typography.PaneHeader">
        @Dialog.Instance.Parameters.Title
    </FluentLabel>
  </FluentStack>
</FluentDialogHeader>



以下程式碼建立對話盒的尾部部分。「FluentDialogFooter」是對話盒的底部,裡面包含了兩個按鈕,一個是刪除按鈕,點擊後會執行「DeleteAsync」方法,另一個是取消按鈕,點擊後會執行「CancelAsync」方法。

1
2
3
4
5
@* Footer *@
<FluentDialogFooter>
  <FluentButton Appearance = "Appearance.Accent" OnClick = "@DeleteAsync"> Delete </FluentButton>
  <FluentButton Appearance = "Appearance.Neutral" OnClick = "@CancelAsync"> Cancel </FluentButton>
</FluentDialogFooter>


以下程式碼建立對話盒的主體部分。「FluentDialogBody」是對話盒的主體,裡面包含了三個文字欄位,分別繫結到「Content」物件的「CustomerId」、「CompanyName」和「ContactName」屬性。

 

 

1
2
3
4
5
6
@* Body *@
<FluentDialogBody>
  <FluentTextField @bind-Value = "@Content.CustomerId"> Id: </FluentTextField>
  <FluentTextField @bind-Value = "@Content.CompanyName"> CompanyName: </FluentTextField>
  <FluentTextField @bind-Value = "@Content.ContactName"> ContactName: </FluentTextField>
</FluentDialogBody>

 

 


以下程式碼定義一些屬性和方法。「Content」屬性是一個參數,它的類型是「FluentUIDataGrid.Models.Customer」。「Dialog」性是一個「CascadingParameter」參數,它的類型是「FluentDialog」。「DeleteAsync」方法是在刪除按鈕被按下時執行,它會關閉對話盒並傳遞「Content」物件。「CancelAsync」方法是在取消按鈕被按下時執行,它會取消對話盒。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@code {
  [Parameter]
  public FluentUIDataGrid.Models.Customer Content { get; set; } = default!;
 
  [CascadingParameter]
  public FluentDialog Dialog { get; set; } = default!;
 
  private async Task DeleteAsync() {
    await Dialog.CloseAsync( Content );
  }
 
  private async Task CancelAsync() {
    await Dialog.CancelAsync( );
  }
}

 

 


下一步在「MyDataGridComponent.razor」元件中使用「MyDialog」對話盒。參考以下程式碼,當按下「FluentDataGrid 」任一筆資料右方的刪除按鈕時,便叫用「DialogService.ShowDialogAsync()」方法顯示自訂對話盒:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@using FluentUIDataGrid.Models
@using Microsoft.EntityFrameworkCore
@inject NorthwindContext DbContext
@inject IDialogService DialogService
<h3>MyDataGridComponent</h3>
<FluentDataGrid  TGridItem = "Customer" Items = "Customers" GridTemplateColumns = "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr">
  <PropertyColumn Property = "@(c => c.CustomerId)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.CompanyName)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.ContactName)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.ContactTitle)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.Address)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.City)" Sortable = "true" />
  <PropertyColumn Property = "@(c => c.Country)" Sortable = "true" />
  <TemplateColumn Title = "Actions">
    <FluentButton IconStart = "@(new Icons.Regular.Size20.Delete())" OnClick = "@( () => DeleteClicked(context) )">
      Delete
    </FluentButton>
  </TemplateColumn>
</FluentDataGrid>
 
 
@code {
 
  public async Task DeleteClicked( Customer customer ) {
    var dialog = await DialogService.ShowDialogAsync<FluentUIDataGrid.Shared.MyDialog>(
      customer, new DialogParameters {
          Height = "240px",
          Title = $"Delete Customer : { customer.CustomerId }",
          PreventDismissOnOverlayClick = true,
          PreventScroll = true
        } );
 
    var result = await dialog.Result;
    if ( !result.Cancelled && result.Data != null ) {
      var c = await DbContext.Customers.FirstOrDefaultAsync( c => c.CustomerId == customer.CustomerId );
      DbContext.Customers.Remove( c );
      if ( c is not null ) {
        await DbContext.SaveChangesAsync( );
      }
    }
  }
 
 
  public IQueryable<Customer> Customers { get; set; } = null!;
  protected override async Task OnInitializedAsync() {
 
    await Task.Run( () => {
      Customers = DbContext.Customers.AsQueryable( );
    } );
  }
}
 
<style>
  .dialog-box {
    background-color: #f2f2f2;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 10px;
    margin-bottom: 10px;
  }
 
  .dialog-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 10px;
  }
 
  .dialog-buttons {
    margin-top: 10px;
  }
 
    .dialog-buttons button {
      margin-right: 10px;
    }
</style>

 

 

 

分別說明如下,以下這段程式碼,叫用「DialogService.ShowDialogAsync()」方法顯示對話盒,傳入了一個「customer」物件和一個「DialogParameters」物件來設定對話盒的參數,「Height」設定高度、「Title」設定標題、「PreventDismissOnOverlayClick」是否防止點選背景來關閉對話盒,「PreventDismissOnOverlayClick」設定為「true」時不可以點選背景來關閉對話盒;「PreventDismissOnOverlayClick」設為「false」則可以點選背景來關閉對話盒、「PreventScroll」用來設定是否防止滾動。

 

 

1
2
3
4
5
6
7
var dialog = await DialogService.ShowDialogAsync<FluentUIDataGrid.Shared.MyDialog>(
      customer, new DialogParameters {
          Height = "240px",
          Title = $"Delete Customer : { customer.CustomerId }",
          PreventDismissOnOverlayClick = true,
          PreventScroll = true
        } );

 


以下這行程式碼是在等待對話盒關閉並獲取結果,如果對話盒沒有被取消且返回的資料不為空,則進行以下操作:首先,從資料庫中找尋與當前「customer」的「CustomerId」相符的「Customer」物件。然後,從「DbContext.Customers」移除該筆資料。最後,如果「CustomerId」相符的資料存在於資料庫,則刪除資料庫的資料:

 

 

1
2
3
4
5
6
7
8
var result = await dialog.Result;
if ( !result.Cancelled && result.Data != null ) {
  var c = await DbContext.Customers.FirstOrDefaultAsync( c => c.CustomerId == customer.CustomerId );
  DbContext.Customers.Remove( c );
  if ( c is not null ) {
    await DbContext.SaveChangesAsync( );
  }
}

 

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


圖 1:自訂對話盒。







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

Related Posts:

  • 使用ChatGPT API快速實作翻譯機許嘉仁 Jerry hsu恆逸教育訓練中心-資深講師技術分類:程式設計 本篇文章的內容會需要使用者先註冊OpenAI帳戶,並且需要登記信用卡資訊以及儲值才能使用,相關的註冊方式可以參考網路上的影片。另外透過官網的操作介面建立並取得呼叫API所需要的API Key,這樣才能開始使用… Read More
  • 程式設計新手入門最適合的程式語言-Java Python .net C# JavaScript怎麼選當學習程式語言已經變成全民運動,甚至連中小學生都要開始學程式,有興趣想要進入這個產業的你一定會好奇,這麼多種程式語言,哪些是比較適合新手學習呢?以下提供幾個方向給大家思考:自己的學習目的:想解決生活上的問題、想朝專職程式設計師發展、想發展第二專長等自己的興趣:如對喜歡電子元器件、晶片比較感興趣,可以… Read More
  • 資訊界最有價值的證照,恆逸一次統統整理給你! ➧證照:最好的實力證明 越來越多企業公司,找尋人才首重證照而非學歷!擁有證照的人,往往在老闆心目中都是優先升遷與加薪,擁有一張黃金證照在找工作時,更容易取得面試官的優先錄取;就算是要轉換跑道,擁有證照也能夠快速進入不同領域,以證明自己有足夠的能力勝認工作! 目前資訊產… Read More
  • 如何處理集合型態物件的 ConcurrentModificationException不知道大家有沒有遇到過,開發功能中若使用集合型態物件(無論是宣告為區域變數或屬性),常利用迴圈(while+Iterator或forEach)逐個取得集合元素。若此時需要在迴圈中移除(最後一個以外的)某個元素,並進入下一個元素(next( )方法)時,會發生ConcurrentModificatio… Read More
  • 為IT職涯做好準備!【恆逸達人學習故事】林仲昱:追求卓越,從學習開始!取得多張IT證照,讓每個現在更好,讓每個明天更美!▍ 恆逸達人學習故事  ▍資訊技術不斷推陳出新,想讓IT職涯發展更順遂需要不斷的精進技能但是各種不同的技術課程與學習資源,該如何選擇最適合自己的呢?本專欄分享來自各行各業IT人在恆逸的學習故事從初入社會的新鮮人、到專業IT工程師、一路到技術主管或管理職在職涯的不同階段,仍持續回到… Read More

0 意見:

張貼留言