ASP.NET Core BlazorQuickGrid コンポーネント

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

QuickGrid コンポーネントは、データを表形式ですばやく効率的に表示するための Razor コンポーネントです。 QuickGrid では、グリッドをレンダリングする一般的なシナリオに向けたシンプルで便利なデータ グリッド コンポーネントが提供されます。データ グリッド コンポーネントを構築するための参照アーキテクチャとパフォーマンス ベースラインとして機能します。 QuickGrid は高度に最適化されており、高度な手法を使って最適なレンダリング パフォーマンスを実現します。

Package

Microsoft.AspNetCore.Components.QuickGrid パッケージのパッケージ参照を追加します。

Note

.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 コンポーネントや、指定された PaginationState インスタンスを表示および更新する他の UI ロジックと組み合わせて使います。
  • QuickGrid の子コンテンツ (RenderFragment) で、PropertyColumn<TGridItem,TProp> を指定します。これは、そのセルに値が表示される TGridItem 列を表します。
    • Property: この列のセルに表示される値を定義します。
    • Format: 必要に応じて、値の書式指定文字列を指定します。 Format を使う場合は、IFormattable を実装する TProp 型が必要になります。
    • Sortable: この列でデータを並べ替え可能にするかどうかを示します。 既定値は、列の型によって異なる場合があります。 たとえば、TemplateColumn<TGridItem> は、SortBy パラメーターが指定されている場合、既定で並べ替え可能です。
    • InitialSortDirection: IsDefaultSortColumntrue の場合に、並べ替えの方向を示します。
    • IsDefaultSortColumn: 既定でこの列を並べ替える必要があるかどうかを示します。
    • PlaceholderTemplate: 指定した場合、仮想化されたグリッドではこのテンプレートを使って、データが読み込まれていないセルをレンダリングします。
    • HeaderTemplate: この列のヘッダー セル用の、省略可能なテンプレート。 指定されない場合は、既定のヘッダー テンプレートには Title と、適用される並べ替えインジケーターとオプション ボタンが含まれます。
    • Title: 列のタイトル テキスト。 HeaderTemplate が使用されていない場合は、タイトルは自動的にレンダリングされます。
  • 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 コンポーネントや、指定された PaginationState インスタンスを表示および更新する他の UI ロジックと組み合わせて使います。
  • QuickGrid の子コンテンツ (RenderFragment) で、PropertyColumn<TGridItem,TProp> を指定します。これは、そのセルに値が表示される TGridItem 列を表します。
    • Property: この列のセルに表示される値を定義します。
    • Format: 必要に応じて、値の書式指定文字列を指定します。 Format を使う場合は、IFormattable を実装する TProp 型が必要になります。
    • Sortable: この列でデータを並べ替え可能にするかどうかを示します。 既定値は、列の型によって異なる場合があります。 たとえば、TemplateColumn<TGridItem> は、SortBy パラメーターが指定されている場合、既定で並べ替え可能です。
    • InitialSortDirection: IsDefaultSortColumntrue の場合に、並べ替えの方向を示します。
    • IsDefaultSortColumn: 既定でこの列を並べ替える必要があるかどうかを示します。
    • PlaceholderTemplate: 指定した場合、仮想化されたグリッドではこのテンプレートを使って、データが読み込まれていないセルをレンダリングします。
    • HeaderTemplate: この列のヘッダー セル用の、省略可能なテンプレート。 指定されない場合は、既定のヘッダー テンプレートには Title と、適用される並べ替えインジケーターとオプション ボタンが含まれます。
    • Title: 列のタイトル テキスト。 HeaderTemplate が使用されていない場合は、タイトルは自動的にレンダリングされます。

たとえば、次のコンポーネントを追加してグリッドをレンダリングします。

コンポーネントでは、対話型サーバー レンダリング モード (InteractiveServer) が親コンポーネントから継承されるか、アプリにグローバルに適用されることが想定されており、対話型機能が有効になります。 次の例では、対話型機能は並べ替え可能な列のみです。

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();
}

QuickGrid コンポーネントは、データを表形式ですばやく効率的に表示するための試験的な Razor コンポーネントです。 QuickGrid では、グリッドをレンダリングする一般的なシナリオに向けたシンプルで便利なデータ グリッド コンポーネントが提供されます。データ グリッド コンポーネントを構築するための参照アーキテクチャとパフォーマンス ベースラインとして機能します。 QuickGrid は高度に最適化されており、高度な手法を使って最適なレンダリング パフォーマンスを実現します。

QuickGrid の使用を開始するには:

パッケージの プレリリース パッケージ参照を Microsoft.AspNetCore.Components.QuickGrid 追加します。 .NET CLI を使ってパッケージ参照を追加する場合は、dotnet add package コマンドの実行時に --prerelease オプションを含めます。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

注意

Microsoft.AspNetCore.Components.QuickGridこのパッケージは .NET 7 の実験的なパッケージであるため、.NET 7 Blazorアプリの場合、パッケージはプレリリース状態のままとなります。 このパッケージが .NET 8 以降の運用状態に達しました。 詳細については、この記事のバージョン 8.0 以降を参照してください。

次のコンポーネントを追加してグリッドをレンダリングします。

PromotionGrid.razor:

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

<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 にあるコンポーネントにアクセスします。

現時点では、本格的な商用グリッドが提供するような機能、たとえば階層型の行、ドラッグして並べ替える列、Excel に似た範囲の選択などによって、QuickGrid を拡張する計画はありません。 独自に開発する予定のない高度な機能が必要な場合は、引き続きサードパーティ製のグリッドをお使いください。

カスタム属性とスタイル

QuickGrid では、レンダリングされたテーブル要素にカスタム属性とスタイル クラスを渡すことがサポートされています。

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

Entity Framework Core (EF Core) データ ソース

EF Core の DbContext は、データベース内の各テーブルに対して DbSet<TEntity> プロパティを提供します。 Items パラメーターにプロパティを指定します。

次の例では、PeopleDbSet<TEntity> (テーブル) をデータ ソースとして使用します。

@inject ApplicationDbContext AppDbContext

<QuickGrid Items="@AppDbContext.People">
    ...
</QuickGrid>

EF でサポートされている LINQ 演算子を使用して、Items パラメーターに渡す前にデータをフィルター処理することもできます。

次の例では、カテゴリ ID でドキュメントをフィルター処理します。

<QuickGrid Items="@AppDbContext.Documents.Where(d => d.CategoryId == categoryId)">
    ...
</QuickGrid>

QuickGrid は、EF 提供の IQueryable インスタンスを認識し、効率を高めるためにクエリを非同期的に解決する方法を認識しています。

Microsoft.AspNetCore.Components.QuickGrid.EntityFrameworkAdapter NuGet パッケージのパッケージ参照を追加して開始します。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

Program ファイルのサービス コレクションで AddQuickGridEntityFrameworkAdapter を呼び出し、IAsyncQueryExecutor の EF に対応した実装を登録します。

builder.Services.AddQuickGridEntityFrameworkAdapter();

表示名のサポート

列のタイトルは、PropertyColumn<TGridItem,TProp> のタグ内で ColumnBase<TGridItem>.Title を使用して割り当てることができます。 次の例では、列の映画公開日データに合わせて "Release Date" という名前がこの列に付けられています。

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

ただし、列のタイトル (名前) の管理はバインドされたモデル プロパティから行うほうが一般的に、アプリの保守のためには良い選択肢です。 モデルによってプロパティの表示名を制御するには、[Display] 属性を使用します。 次の例では、モデルによって映画公開日の表示名 "Release Date" が ReleaseDate プロパティに対して指定されています。

[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 パラメーターを使用します。

ItemsProvider は、アプリが外部エンドポイントのクエリを実行する必要がある場合や、要件が IQueryable でカバーされていない場合に、サーバー側の Blazor アプリでも使用できます。

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 スキャフォールディング

QuickGrid スキャフォールディングは Razor コンポーネントを QuickGrid でスキャフォールディングし、データベースからのデータを表示します。

スキャフォールディングによって、Entity Framework Core データ モデルに基づいた基本的な作成、読み取り、更新、削除 (CRUD) ページが生成されます。 個々のページまたはすべての CRUD ページをスキャフォールディングできます。 モデル クラスと DbContext を選択し、必要に応じて DbContext を作成します (省略可能)。

スキャフォールディングされた Razor コンポーネントは、モデル クラスに基づいた名前で生成されたフォルダー内にあるプロジェクトの Pages フォルダーに追加されます。 生成された Index コンポーネントは、QuickGrid を使用してデータを表示します。 生成されたコンポーネントを必要に応じてカスタマイズし、対話機能を有効にして、並べ替えやフィルター処理などの対話型機能を利用できるようにします。

スキャフォールディングによって生成されるコンポーネントにはサーバー側レンダリング (SSR) が必要であるため、WebAssembly で実行する場合はサポートされません。

スキャフォールディングを使用するには、ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]>[New Scaffolded Item] (新規スキャフォールディング項目) を選択します。 [インストール済み]>[共通]>[Razor コンポーネント] を選択します。 [Razor Components using Entity Framework (CRUD)] (Entity Framework を使用する Razor コンポーネント (CRUD)) を選択します。 .NET CLI でスキャフォールディングを使用するには、ASP.NET Core コード ジェネレーター ツール ('aspnet-codegenerator') についての記事をご覧ください。