Blazor建立TabControl元件

Blazor建立TabControl元件

建立一個Blazor TabControl元件,有兩個目標知識點

最後更新 2021/12/6 下午10:01
Blazor University
預計閱讀 4 分鐘
分類
Blazor
標籤
.NET Blazor 前端

不是全文翻译,部分翻译自認為可能不準確,就原文照搬了。

建立一個 Blazor TabControl 元件,有兩個目標知識點:

  1. 將資料傳入 RenderFragment 中,賦予它上下文(context)。
  2. 使用 CascadingParameter 將父層 TabControl 元件傳遞給其子層 TabPage 元件。

下面看最終效果圖:

實作開始:

請先建立一個 Blazor 專案(Blazor Client 或 Server 皆可,我們以 Blazor Server 為例),

第一步,建立兩個元件:TabControlTabPageTabPage 元件有一個父層 TabControl 屬性參考(屬性名 Parent,加上 CascadingParameter 特性)。

TabControl 元件:

檔案路徑:./Shared/TabControl.razor

<div>這是一個 TabControl</div>
<CascadingValue Value="this"> @ChildContent </CascadingValue>

@code { // 如果我們想以 <TabPage> 標籤的形式使用 TabPage,那麼下面的程式碼是必須的 [Parameter] public
  RenderFragment? ChildContent { get; set; } }

TabPage 元件:

檔案路徑:./Shared/TabPage.razor

<div>這是一個 TabPage</div>
@ChildContent @code { [CascadingParameter] private TabControl? Parent { get;
set; } [Parameter] public RenderFragment? ChildContent { get; set; } protected
override void OnInitialized() { if (Parent == null) throw new
ArgumentNullException(nameof(Parent), "TabPage 必須包含 TabControl 參考");
base.OnInitialized(); } }

TabControl 關聯 TabPage

TabPageOnInitialized 方法中加入下面這一行程式碼,使 TabPage 關聯上 TabControl

Parent.AddPage(this);

AddPage 方法見下面的程式碼,在 TabControl 呼叫 AddPage 方法儲存參考後,我們在 TabControl 中加入 ActivePage 屬性,同樣看下面的程式碼:

public TabPage? ActivePage { get; set; }
readonly List<TabPage> _pages = new();

internal void AddPage(TabPage tabPage)
{
    _pages.Add(tabPage);
    if (_pages.Count == 1)
        ActivePage = tabPage;
    StateHasChanged();
}

TabPage 元件加上一個 Text 屬性用於顯示。

[Parameter]
public string? Text { get; set; }

TabControl 中加入以下標籤(在 ChildContent 渲染之前),這些標籤會一次性全部渲染出來,當點擊某個 TabPage 時會改變 TabControl 的選擇項。

<div class="btn-group" role="group">
  @foreach (TabPage tabPage in Pages)
  {
    <button type="button"
      class="btn @GetButtonClass(tabPage)"
      @onclick=@( ()=>ActivatePage(tabPage) )>
      @tabPage.Text
    </button>
  }
</div>

上面這些標籤會建立標準的 Bootstrap 按鈕群組,每個 TabPage 會建立一個有以下特徵的按鈕:

  1. CSS 類別設為 "btn",並透過 GetButtonClass 方法追加 CSS 類別名稱,如果目前 TabPageActivePage,加入 CSS 類別 btn-primary,否則加入 btn-secondary
  2. 當點擊按鈕時會啟動點擊的 TabPage

注意@onclick 需要關聯一個無參數的方法,所以 lambda 運算式用一個內聯的 @( ) 來設定點擊的 TabPageActivatePage

  1. 按鈕的文字透過 TabPageText 屬性設定。

下面的程式碼加入到 TabControl 的程式碼區域。

string GetButtonClass(TabPage page)
{
  return page == ActivePage ? "btn-primary" : "btn-secondary";
}
void ActivatePage(TabPage page)
{
  ActivePage = page;
}

使用 TabControl

加入一個 TabControlTest 元件:

檔案名稱:./Pages/TabControlTest.razor

@page "/tabcontroltest"

<TabControl>
  <TabPage Text="Tab 1">
    <h1>The first tab</h1>
  </TabPage>
  <TabPage Text="Tab 2">
    <h1>The second tab</h1>
  </TabPage>
  <TabPage Text="Tab 3">
    <h1>The third tab</h1>
  </TabPage>
</TabControl>

@code { }

在 ./Shared/NavMenu 中加入 TabControlTest 路由

省略部分程式碼
<div class="nav-item px-3">
  <NavLink class="nav-link" href="tabcontroltest">
    <span class="oi oi-plus" aria-hidden="true"></span> TabControl Test
  </NavLink>
</div>
省略部分程式碼

這樣就完了嗎?我們看看現在的效果:

不對吧,三個 TabPage 的內容全部顯示出來了,解決這個問題只需要在 TabPage 渲染 ChildContent 時判斷目前 TabPage 是否為 TabControl 選取的頁面,選取項才進行渲染:

@if (Parent.ActivePage == this)
{
  @ChildContent
}

OK 程式碼完成,效果見本文開頭。

文中程式碼已放:GitHub

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2021/12/30

Blazor系列終結!

Blazor系列轉載`終結啦`,其實站長在25號時就已`完成轉載`,並同步在`Dotnet9`網站(`https://dotnet9.com`)發佈,並創建了一個專輯`《大家一起學Blazor》`,大家可隨時在網站瀏覽。

繼續閱讀
同分類 / 同標籤 2024/2/29

Winform中也可以這樣做資料展示

在做winform開發的過程中,經常需要做資料展示的功能,之前一直使用的是gridcontrol控制項,今天想透過一個範例,跟大家介紹一下如何在winform blazor hybrid中使用ant design blazor中的table元件做資料展示。

繼續閱讀
同分類 / 同標籤 2024/2/29

Winform的介面也可以變好看?

前幾天跟大家介紹了在winform中使用blazor hybrid,而且還說配上blazor的UI可以讓我們的winform程式設計的更加好看,接下來我想以一個在winform blazor hybrid中繪圖的範例來進行說明,希望對你有所幫助。

繼續閱讀