BodyTemplate を使ってセルのレンダリング内容をカスタマイズする
Blazor 向け UI コンポーネント製品 Ignite UI for Blazor が提供するグリッドコンポーネント、IgbGrid について、そのセル内にハイパーリンクを配置したい場合は、セル内のレンダリング内容を完全にカスタマイズできる BodyTemplate を使う方法があります。
IgbGrid コンポーネントのマークアップ内で IgbColumn コンポーネントを使って列を定義する際に、その IgbColumn コンポーネント内に <BodyTemplate> とマークアップすると、その列のセルのレンダリング内容が <BodyTemplate> 内に記述した内容で完全に置き換えられます。
この BodyTtemplate を使うことで、所定の列のセルのレンダリング内容を <a> タグによるハイパーリンクに差し替えることが可能です。以下にコード例を示します。
<IgbGrid Data="_products" AutoGenerate="false" PrimaryKey="@nameof(Product.Id)"> <IgbColumn Field="@nameof(Product.Id)" Header="ID" Width="10%" /> <IgbColumn Field="@nameof(Product.Name)" Header="製品名" Width="30%" /> <IgbColumn Field="@nameof(Product.URL)" Header="製品紹介ページ" Width="60%"> <BodyTemplate> <a href="@context.Cell.Value" target="_blank"> @context.Cell.Value </a> </BodyTemplate> </IgbColumn> </IgbGrid> @code { private record Product(int Id, string Name, string URL); private readonly IEnumerable<Product> _products = [ new(1, "Ignite UI for Blazor", "https://jp.infragistics.com/products/ignite-ui-blazor"), new(2, "Ignite UI for Angular", "https://jp.infragistics.com/products/ignite-ui-angular"), new(3, "Ignite UI for React", "https://jp.infragistics.com/products/ignite-ui-react"), new(4, "Ignite UI for Web Components", "https://jp.infragistics.com/products/ignite-ui-web-components"), ]; }
上記コード例の実行例は以下のようになります。
上記コード内で出てくる “context” などについて詳しくは、以下のナレッジベース記事が参考になります。下記をご参照いただきますと、上記コード例において、リンク先は Product.URL を使用しつつ、表示テキストは Product.Name を使用する、といったことも可能です。
IgbGrid – セルのテンプレート内から、該当する行データや、同行の任意の列値を参照する方法 – INFRAGISTICS ナレッジ ベース
より高いパフォーマンスが求められる場合
なお、データ件数や Blazor WebAssembly か Blazor Serevr かの違いなどによって、<BodyTemplate> を使用した場合に、表示速度が重くなる場合があるかもしれません。その場合は、残念ながら C# だけでは完結しないものの、JavaScript による実装とすることで処理性能を引き上げることが可能です。
具体的には <BodyTempate> は使わずに、IgbColumn の BodyTemplateScript に、”igRegisterScript” JavaScript 関数に登録したスクリプト名を指定することで実現します。以下に例を示します。
まず以下のように、セル内容の DOM オブジェクトを返す関数を定義して、Ignite UI for Blazor によって提供される igRegisterScript 関数に、登録名を添えて登録します。igRegisterScript 関数について詳しくは、下記リンク先のナレッジベース記事を参照ください。
Ignite UI for Blazor – igRegisterScript, igRemoveScript の使い方 – INFRAGISTICS ナレッジ ベース
セル内容を返す関数には、その引数にコンテキストが渡されますので、その引数に渡されたコンテキスト変数をたどると、行データまで参照可能となっており、これら情報をもとに a 要素を構築して、この関数から返すようにします。
/* wwwroot/script.js */ igRegisterScript("urlColumnTemplate", (context) => { // 引数 context には、セルの情報が格納されており、行データまで参照可能です。 const productName = context.cell.row.data.Name; const productUrl = context.cell.row.data.URL; // セル内に表示する DOM 要素を生成して返却します。 const a = document.createElement("a"); a.textContent = productName; a.href = productUrl; return a; }, false)
こうして作成した JavaScript ファイルを、フォールバックページ (Blazor WebAssembly であれば wwwroot/index.html) 内に script タグで読み込んでおきます。
<!DOCTYPE html> <html lang="en"> ... <script src="_content/IgniteUI.Blazor/app.bundle.js"></script> <script src="script.js"></script> <script src="_framework/blazor.webassembly.js"></script> </body> </html>
あとは、IgbColumn コンポーネントにて、BodyTemplateScript パラメーターに、先の JavaScript にて igRegisterScript 関数に指定した名前を指定します。
<IgbGrid ...> ... <IgbColumn Field="@nameof(Product.URL)" Header="製品紹介ページ" Width="60%" BodyTemplateScript="urlColumnTemplate" /> </IgbGrid>
以上で下図のように、JavaScript によるセルのレンダリング内容のカスタマイズが実現します。
なお、上記実装例における JavaScript では、ブラウザの DOM API を直に使って、セル内の表示要素を構築していましたが、Ignite UI for Blazor に付属の HTML テンプレート機能 (igTemplating) を使って、以下のようにも実装可能です。
/* wwwroot/script.js */ igRegisterScript("urlColumnTemplate", (context) => { const productName = context.cell.row.data.Name; const productUrl = context.cell.row.data.URL; return igTemplating.html`<a href="${productUrl}">${productName}</a>`; }, false)
上記コードにある igTemplating について詳しくは、下記リンク先のナレッジベース記事を参照ください。
Ignite UI for Blazor – igTemplating の使い方 – INFRAGISTICS ナレッジ ベース
以上のサンプルプログラム全体は以下のリンク先から入手・アクセス頂けます。