共用方式為


ASP.NET Core BlazorQuickGrid 元件

QuickGrid 元件是 Razor 元件,可快速且有效率地以表格格式顯示資料。 QuickGrid 為常見的格線轉譯案例提供簡單且方便的資料格元件,並作為建置資料格線元件的參考架構和效能基準。 QuickGrid 已高度最佳化,並使用進階技巧來達到最佳轉譯效能。

套件

新增 Microsoft.AspNetCore.Components.QuickGrid 套件的套件參考。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

範例應用程式

如需各種 QuickGrid 示範,請參閱 QuickGrid for Blazor 範例應用程式。 示範網站裝載於 GitHub Pages 上。 多虧使用社群維護的 BlazorWasmPrerendering.Build GitHub 專案進行靜態預先轉譯,網站才能快速載入。

QuickGrid 實作

若要實作 QuickGrid 元件:

  • 在 Razor 標記中指定 QuickGrid 元件的標籤 (<QuickGrid>...</QuickGrid>)。
  • 為格線命名可查詢的資料來源。 使用下列任一資料來源:
    • Items:可為 Null 的 IQueryable<TGridItem>,其中 TGridItem 是格線中每個資料列所代表的資料類型。
    • ItemsProvider:提供格線資料的回呼。
  • Class:選擇性 CSS 類別名稱。 若已提供,則類別名稱會包含在轉譯資料表的 class 屬性中。
  • Theme:主題名稱 (預設值:default)。 這會影響哪些樣式規則符合資料表。
  • Virtualize:若為 true,則會使用虛擬化轉譯格線。 這通常搭配捲動使用,並導致格線只擷取和轉譯目前捲動檢視區周圍的資料。 這可大幅改善捲動大型資料集時的效能。 如果您使用 Virtualize,則應該提供 ItemSize 的值並確保每個資料列都會以常數高度轉譯。 一般而言,如果轉譯的資料量很小,或者如果您使用分頁,最好不要使用 Virtualize
  • ItemSize:只有在使用 Virtualize 時適用。 ItemSize 為每個資料列定義預期的高度 (以像素為單位),讓虛擬化機制擷取正確的項目數以符合顯示大小並確保捲動正確。
  • ItemKey:選擇性地在每個轉譯的資料列上定義 @key 的值。 這通常用來指定每個資料項目的唯一識別碼,例如主索引鍵值。 即使 TGridItem 執行個體由新的複本所取代 (例如,在針對基礎資料存放區進行新的查詢之後),這也可讓格線根據唯一識別碼來保留資料列元素與資料項目之間的關聯。 若未設定,則 @keyTGridItem 執行個體。
  • OverscanCount:定義在可見區域前後轉譯多少其他項目,以減少捲動期間的轉譯頻率。 雖然較高的值可以藉由在螢幕外轉譯更多項目來改善捲動平滑度,但較高的值也會導致初始載入時間增加。 建議您根據您的資料集大小和使用者體驗需求來尋找平衡點。 預設值是 3。 只有使用 Virtualize 時才可使用。
  • Pagination:選擇性地將此 TGridItem 執行個體與 PaginationState 模型連結,以致格線只擷取和轉譯目前的資料頁面。 這通常與 Paginator 元件或其他 UI 邏輯搭配使用,以顯示和更新所提供的 PaginationState 執行個體。
  • QuickGrid 子系內容 (RenderFragment) 中,指定 PropertyColumn<TGridItem,TProp>,其代表儲存格顯示值的 TGridItem 資料行:
  • 在 Razor 標記中指定 QuickGrid 元件的標籤 (<QuickGrid>...</QuickGrid>)。
  • 為格線命名可查詢的資料來源。 使用下列任一資料來源:
    • Items:可為 Null 的 IQueryable<TGridItem>,其中 TGridItem 是格線中每個資料列所代表的資料類型。
    • ItemsProvider:提供格線資料的回呼。
  • Class:選擇性 CSS 類別名稱。 若已提供,則類別名稱會包含在轉譯資料表的 class 屬性中。
  • Theme:主題名稱 (預設值:default)。 這會影響哪些樣式規則符合資料表。
  • Virtualize:若為 true,則會使用虛擬化轉譯格線。 這通常搭配捲動使用,並導致格線只擷取和轉譯目前捲動檢視區周圍的資料。 這可大幅改善捲動大型資料集時的效能。 如果您使用 Virtualize,則應該提供 ItemSize 的值並確保每個資料列都會以常數高度轉譯。 一般而言,如果轉譯的資料量很小,或者如果您使用分頁,最好不要使用 Virtualize
  • ItemSize:只有在使用 Virtualize 時適用。 ItemSize 為每個資料列定義預期的高度 (以像素為單位),讓虛擬化機制擷取正確的項目數以符合顯示大小並確保捲動正確。
  • ItemKey:選擇性地在每個轉譯的資料列上定義 @key 的值。 這通常用來指定每個資料項目的唯一識別碼,例如主索引鍵值。 即使 TGridItem 執行個體由新的複本所取代 (例如,在針對基礎資料存放區進行新的查詢之後),這也可讓格線根據唯一識別碼來保留資料列元素與資料項目之間的關聯。 若未設定,則 @keyTGridItem 執行個體。
  • Pagination:選擇性地將此 TGridItem 執行個體與 PaginationState 模型連結,以致格線只擷取和轉譯目前的資料頁面。 這通常與 Paginator 元件或其他 UI 邏輯搭配使用,以顯示和更新所提供的 PaginationState 執行個體。
  • QuickGrid 子系內容 (RenderFragment) 中,指定 PropertyColumn<TGridItem,TProp>,其代表儲存格顯示值的 TGridItem 資料行:

例如,新增下列元件來轉譯格線。

對於 Blazor Web Apps,QuickGrid 元件必須採用互動式轉譯模式以啟用互動式功能,例如分頁和排序。

PromotionGrid.razor

@page "/promotion-grid"
@using Microsoft.AspNetCore.Components.QuickGrid

<PageTitle>Promotion Grid</PageTitle>

<h1>Promotion Grid Example</h1>

<QuickGrid Items="people">
    <PropertyColumn Property="@(p => p.PersonId)" Sortable="true" />
    <PropertyColumn Property="@(p => p.Name)" Sortable="true" />
    <PropertyColumn Property="@(p => p.PromotionDate)" Format="yyyy-MM-dd" Sortable="true" />
</QuickGrid>

@code {
    private record Person(int PersonId, string Name, DateOnly PromotionDate);

    private IQueryable<Person> people = new[]
    {
        new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
        new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
        new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
        new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
        new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
        new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
    }.AsQueryable();
}

在瀏覽器中的相對路徑 /promotion-grid 存取元件。

目前沒有計劃使用成熟商業格線傾向提供的功能來擴充 QuickGrid,例如階層式資料列、拖曳重排資料行,或類似 Excel 的範圍選取。 如果您需要不想自行開發的進階功能,請繼續使用第三方格線。

依資料行排序

QuickGrid 元件可以依資料行排序項目。 在 Blazor Web Apps 中,排序需要元件採用互動式轉譯模式

Sortable="true" (Sortable) 新增至 PropertyColumn<TGridItem,TProp> 標籤:

<PropertyColumn Property="..." Sortable="true" />

在執行中的應用程式中,選取轉譯的資料行標題來排序 QuickGrid 資料行。

具有 Paginator 元件的頁面項目

QuickGrid 元件可以對來自資料來源的資料進行分頁。 在 Blazor Web Apps 中,分頁需要元件採用互動式轉譯模式

PaginationState 執行個體新增至元件的 @code 區塊。 將 ItemsPerPage 設定為每個頁面要顯示的項目數。 在下列範例中,執行個體名稱為 pagination,而每個頁面設定 10 個項目:

PaginationState pagination = new PaginationState { ItemsPerPage = 10 };

QuickGrid 元件的 Pagination 屬性設定為 pagination

<QuickGrid Items="..." Pagination="pagination">

若要提供分頁的 UI,請在 QuickGrid 元件上方、下方或上方和下方新增一個 Paginator 元件。 將 Paginator.State 設定為 pagination

<Paginator State="pagination" />

在執行中的應用程式中,使用轉譯的 Paginator 元件逐頁瀏覽項目。

自訂屬性和樣式

QuickGrid 也支援將自訂屬性和樣式類別 (Class) 傳遞至轉譯的資料表元素:

<QuickGrid Items="..." custom-attribute="value" Class="custom-class">

Entity Framework Core (EF Core) 資料來源

使用處理站模式來解析提供資料給 QuickGrid 元件的 EF Core 資料庫內容。 如需為何建議處理站模式的詳細資訊,請參閱使用 ASP.NET Core Blazor 搭配 Entity Framework Core (EF Core)

資料庫內容處理站 (IDbContextFactory<TContext>) 會使用 @inject 指示詞插入元件。 處理站方法需要處置資料庫內容,以便元件使用 @implements 指示詞實作 IAsyncDisposable 介面。 QuickGrid 元件的項目提供者是從插入資料庫內容處理站的已建立資料庫內容 (CreateDbContext) 取得的 DbSet<T>

QuickGrid 辨識 EF 提供的 IQueryable 執行個體,也知道如何以非同步方式解析查詢以提高效率。

新增 Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter NuGet 套件的套件參考。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

Program 檔案中的服務集合上呼叫 AddQuickGridEntityFrameworkAdapter,以註冊 EF 感知 IAsyncQueryExecutor 實作:

builder.Services.AddQuickGridEntityFrameworkAdapter();

下列範例使用 AppDbContext 資料庫內容 (context) 中的 ExampleTable DbSet<TEntity> (資料表) 作為 QuickGrid 元件的資料來源:

@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<AppDbContext> DbFactory

...

<QuickGrid ... Items="context.ExampleTable" ...>
    ...
</QuickGrid>

@code {
    private AppDbContext context = default!;

    protected override void OnInitialized()
    {
        context = DbFactory.CreateDbContext();
    }

    public async ValueTask DisposeAsync() => await context.DisposeAsync();
}

在上述範例的程式碼區塊 (@code) 中:

  • context 欄位會儲存資料庫內容,類型為 AppDbContext
  • OnInitialized 生命週期方法會將新的資料庫內容 (CreateDbContext) 指派給插入處理站 (DbFactory) 的 context 欄位。
  • 非同步 DisposeAsync 方法會在處置元件時處置資料庫內容。

您也可以使用任何 EF 支援的 LINQ 運算子篩選資料,再將資料傳遞至 Items 參數。

下列範例會依搜尋方塊中輸入的電影標題來篩選電影。 資料庫內容為 BlazorWebAppMoviesContext,而模型為 Movie。 電影的 Title 屬性會用於篩選作業。

@using Microsoft.AspNetCore.Components.QuickGrid
@using Microsoft.EntityFrameworkCore
@implements IAsyncDisposable
@inject IDbContextFactory<BlazorWebAppMoviesContext> DbFactory

...

<p>
    <input type="search" @bind="titleFilter" @bind:event="oninput" />
</p>

<QuickGrid ... Items="FilteredMovies" ...>
    ...
</QuickGrid>

@code {
    private string titleFilter = string.Empty;
    private BlazorWebAppMoviesContext context = default!;

    protected override void OnInitialized()
    {
        context = DbFactory.CreateDbContext();
    }

    private IQueryable<Movie> FilteredMovies => 
        context.Movie.Where(m => m.Title!.Contains(titleFilter));

    public async ValueTask DisposeAsync() => await context.DisposeAsync();
}

顯示名稱支援

資料行標題可以使用 PropertyColumn<TGridItem,TProp> 標籤中的 ColumnBase<TGridItem>.Title 來指派。 在下列電影範例中,資料行會指定資料行電影上映日期資料的名稱「Release Date」:

<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />

不過,從繫結模型屬性管理資料行標題 (名稱) 通常是維護應用程式的較佳選擇。 模型可以使用 [Display] 屬性來控制屬性的顯示名稱。 在下列範例中,模型會為其 ReleaseDate 屬性指定電影上映日期顯示名稱「Release Date」:

[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }

若要讓 QuickGrid 元件能夠在元件,或在另一個類別中使用 DisplayAttribute.Name、子類別 PropertyColumn<TGridItem,TProp>

public class DisplayNameColumn<TGridItem, TProp> : PropertyColumn<TGridItem, TProp>
{
    protected override void OnParametersSet()
    {
        if (Title is null && Property.Body is MemberExpression memberExpression)
        {
            var memberInfo = memberExpression.Member;
            Title = 
                memberInfo.GetCustomAttribute<DisplayNameAttribute>().DisplayName ??
                memberInfo.GetCustomAttribute<DisplayAttribute>().Name ??
                memberInfo.Name;
        }

        base.OnParametersSet();
    }
}

使用 QuickGrid 元件中的子類別。 在下列範例中,會使用上述 DisplayNameColumn。 名稱「Release Date」是由模型中的 [Display] 屬性提供,因此不需要指定 Title

<DisplayNameColumn Property="movie => movie.ReleaseDate" />

也支援 [DisplayName] 屬性

[DisplayName("Release Date")]
public DateTime ReleaseDate { get; set; }

不過,建議使用 [Display] 屬性,因為它會提供其他屬性。 例如,[Display] 屬性可讓您指派資源類型以進行當地語系化。

遠端資料

在 Blazor WebAssembly 應用程式,從伺服器上的 JSON 型 Web API 擷取資料是常見的需求。 如果只要擷取目前資料頁面/檢視區所需的資料,並在伺服器套用排序或篩選規則,請使用 ItemsProvider 參數。

如果查詢外部端點,或是 IQueryable 未涵蓋需求的其他案例需要應用程式,也可以在伺服器端 Blazor 應用程式使用 ItemsProvider

提供符合 GridItemsProvider<TGridItem> 委派類型的回呼,其中 TGridItem 是格線中顯示的資料類型。 回呼會被指定 GridItemsProviderRequest<TGridItem> 這個型別的參數,它會指定要傳回之資料的起始索引、最大資料列計數和排序順序。 除了傳回相符項目之外,還需要項目總數 (totalItemCount),分頁和虛擬化才能正常運作。

下列範例從公開 OpenFDA Food Enforcement 資料庫取得資料。

GridItemsProvider<TGridItem>GridItemsProviderRequest<TGridItem> 轉換為對 OpenFDA 資料庫的查詢。 查詢參數會轉譯為外部 JSON API 支援的特定 URL 格式。 排序和篩選只能透過外部 API 支援的排序和篩選執行。 OpenFDA 端點不支援排序,因此不會將任何資料行標示為可排序。 不過,它確實支援略過記錄 (skip 參數),以及限制傳回記錄 (limit 參數),因此元件可以啟用虛擬化並快速捲動數萬筆記錄。

FoodRecalls.razor

@page "/food-recalls"
@inject HttpClient Http
@inject NavigationManager NavManager

<PageTitle>Food Recalls</PageTitle>

<h1>OpenFDA Food Recalls</h1>

<div class="grid" tabindex="-1">
    <QuickGrid ItemsProvider="@foodRecallProvider" Virtualize="true">
        <PropertyColumn Title="ID" Property="@(c => c.Event_Id)" />
        <PropertyColumn Property="@(c => c.State)" />
        <PropertyColumn Property="@(c => c.City)" />
        <PropertyColumn Title="Company" Property="@(c => c.Recalling_Firm)" />
        <PropertyColumn Property="@(c => c.Status)" />
    </QuickGrid>
</div>

<p>Total: <strong>@numResults results found</strong></p>

@code {
    GridItemsProvider<FoodRecall>? foodRecallProvider;
    int numResults;

    protected override async Task OnInitializedAsync()
    {
        foodRecallProvider = async req =>
        {
            var url = NavManager.GetUriWithQueryParameters(
                "https://api.fda.gov/food/enforcement.json", 
                new Dictionary<string, object?>
            {
                { "skip", req.StartIndex },
                { "limit", req.Count },
            });

            var response = await Http.GetFromJsonAsync<FoodRecallQueryResult>(
                url, req.CancellationToken);

            return GridItemsProviderResult.From(
                items: response!.Results,
                totalItemCount: response!.Meta.Results.Total);
        };

        numResults = (await Http.GetFromJsonAsync<FoodRecallQueryResult>(
            "https://api.fda.gov/food/enforcement.json"))!.Meta.Results.Total;
    }
}

如需呼叫 Web API 的詳細資訊,請參閱從 ASP.NET Core Blazor 應用程式呼叫 Web API

QuickGrid Scaffolder

QuickGrid Scaffolder 會使用 QuickGrid 來建立 Razor 元件的 Scaffolding 框架,以顯示資料庫中的資料。

此 Scaffolder 會根據 Entity Framework Core 資料模型來產生基本的建立、讀取、更新和刪除 (CRUD) 頁面。 您可以建立個別頁面或所有 CRUD 頁面的 Scaffolding 框架。 您可以選取模型類別和 DbContext,視需要選擇性地建立新的 DbContext

此 Scaffolded Razor 元件會新增至專案中以模型類別命名的產生資料夾中。 產生的 Index 元件會使用 QuickGrid 元件來顯示資料。 視需要自訂產生的元件,並啟用互動功能以利用互動式功能,例如分頁排序和篩選。

此 Scaffolder 所產生的元件需要伺服器端轉譯 (SSR),因此在 WebAssembly 上執行時不支援它們。

以滑鼠右鍵按一下 Components/Pages 資料夾,然後選取 [新增]>[新增 Scaffolded 項目]

在開啟的 [新增 Scaffold 項目] 對話方塊中,進到 [已安裝]>[一般]>[Razor 元件],然後選取 [使用 Entity Framework (CRUD) 的 Razor 元件]。 選取新增按鈕。

完成 [使用 Entity Framework (CRUD) 新增 Razor 元件] 對話方塊:

  • 範本下拉式清單包含其他專門用於建立「建立」、「編輯」、「刪除」、「詳細資料」和「清單」元件的範本。 當您只需要建立 Scaffolded 到模型類別的特定類型的元件時,此下拉式清單會派上用場。 將範本下拉式清單設定為 CRUD 以 Scaffold 一組完整的元件。
  • 在 [模型類別] 下拉式清單中,選取模型類別。 系統會根據模型名稱為產生的元件建立一個資料夾 (如果模型類別名稱為 Movie,則該資料夾會自動命名為 MoviePages)。
  • 針對 DbContext 類別,選取現有的資料庫內容,或選取 + (加號) 按鈕,然後在 [新增資料內容] 模式對話方塊中新增資料庫內容。
  • 在該模式對話方塊關閉後,資料庫提供者下拉式清單會預設為 SQL Server。 您可以為您正在使用的資料庫選取適當的提供者。 這些選項包括 SQL Server、SQLite、PostgreSQL 和 Azure Cosmos DB。
  • 選取 [新增]。