Radzen Blazor DataGrid で同じカラムの前の行の値と異なるセルをハイライトする

# 課題
Radzen Blazor DataGrid コンポーネントで表示している資産管理のデータベースの更新履歴上、同じ資産のひとつ前のレコードのそれぞれのカラムの値を比較して、異なる場合は、そのセルをハイライトさせたい。


# 解決策
RadzenDataGrid コンポーネントの RowRender イベントを利用します。


## サービスクラスの編集
データベースからデータを取得するメソッドを追加
```C#
public class AssetUsageService : IAssetUsageService
{

    private readonly AppDbContext _context;
    
    public AssetUsageService(IDbContextFactory<AppDbContext> context)
    {
        _context = context.CreateDbContext();
    }
    
    public async Task<List<AssetUsage>> GetAllRecords()
    {
        // 取得するデータは並べ替えしない（データベース上、古い順）
        return await _context.AssetUsages
            .Include(au => au.AssetMaster)
            .ToListAsync();
    }
}

```

## コントローラクラスの編集
先に作ったサービスクラスのメソッドを利用して GET アクションメソッドを定義する。
```C#
namespace BlazorApp2.Server.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AssetController : ControllerBase
    {
        private readonly IAssetUsageService _service;

        public AssetController(IAssetUsageService service)
        {
            _service = service;
        }

        // GET: api/asset/history
        [HttpGet("history")]
        public async Task<ActionResult<List<AssetUsage>>> GetUpdateHistory()
        {
            var history = await _service.GetAllRecords();
            if (history == null) return NotFound();
            return history;
        }
    }
}
```

## Razorファイルの編集

HTMLのRadzenDataGrid コンポーネント部分の編集。
```html
@*並べ替え可能に、複数カラムの並べ替えを可能に、並べ替えインデックスを表示する設定に*@
@*RowRender と CellRender に Code 部分で定義する関数をセット*@
<RadzenDataGrid AllowColumnPicking="true" AllowColumnResize="true" ColumnWidth="150px" Style="max-height: 400px;" 
    AllowVirtualization="true" VirtualizationOverscanCount="5"
    AllowFiltering="true" FilterMode="FilterMode.Simple" LogicalFilterOperator="LogicalFilterOperator.And" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
    AllowSorting="true" AllowMultiColumnSorting="true" ShowMultiColumnSortingIndex="true"
    RowRender="@OnRowRender" CellRender="@OnCellRender"
    @ref="grid" Data="@assets" TItem="AssetUsage">
    <Columns>
        @*IDプロパティで降順に並べ替え、並べ替え優先順位を1に*@
        <RadzenDataGridColumn TItem="AssetUsage" Property="ID" Title="ID" SortOrder="SortOrder.Descending" OrderIndex="1" Filterable="false" Frozen="true" />
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetCode" Title="機体番号" Frozen="true" />
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetMaster.SerialNumber" Title="シリアル番号">
            <Template Context="assetUsage">
                @assetUsage.AssetMaster.SerialNumber
            </Template>
        </RadzenDataGridColumn>
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="State" Title="ステータス" />
        @*UpdateDate プロパティで降順に並べ替え、並べ替え優先順位を2に*@
        <RadzenDataGridColumn TItem="AssetUsage" Property="UpdateDate" Title="更新日時" SortOrder="SortOrder.Descending" OrderIndex="2"  />
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="Fault" Title="故障" />
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetMaster.ReferenceID" Title="リース番号">
            <Template Context="assetUsage">
                @assetUsage.AssetMaster.ReferenceID
            </Template>
        </RadzenDataGridColumn>
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetMaster.Agency" Title="リース会社">
            <Template Context="assetUsage">
                @assetUsage.AssetMaster.Agency
            </Template>
        </RadzenDataGridColumn>
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetMaster.ExpireDate" Title="リース期限">
            <Template Context="assetUsage">
                @assetUsage.AssetMaster.ExpireDate
            </Template>
        </RadzenDataGridColumn>
    
        <RadzenDataGridColumn TItem="AssetUsage" Property="AssetMaster.Fee" Title="リース料金">
            <Template Context="assetUsage">
                @assetUsage.AssetMaster.Fee
            </Template>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>

````

C#のコード部分を編集。
```C#

@code {
    private IList<AssetUsage>? assets;
    private RadzenDataGrid<AssetUsage>? grid;

    protected override async Task OnInitializedAsync()
    {
        assets = await Http.GetFromJsonAsync<List<AssetUsage>>("api/asset/history");
    }

    // 以下セルのハイライト関連
    List<AssetUsage>? sameAssets;
    private AssetUsage? previousData;
    int index = 0;
    int rowNum = 0;

    private void OnRowRender(RowRenderEventArgs<AssetUsage> args)
    {
        rowNum++;
        Console.WriteLine($"rowNum: {rowNum}");

        sameAssets = assets.Where(a => a.AssetCode == args.Data.AssetCode).ToList();
        Console.WriteLine($"sameAssets item count: {sameAssets.Count()}");

        index = sameAssets.IndexOf(args.Data);
        Console.WriteLine($"index of sameAssets: {index}");

        if (index > 0)
        {
            previousData = sameAssets[index - 1];
        }
    }

    private void OnCellRender(DataGridCellRenderEventArgs<AssetUsage> args)
    {
        if (index > 0 && previousData != null && args.Data != null && args.Column != null)
        {
            string columnName = args.Column.Property;
            Console.WriteLine($"columnName: {columnName}");

            var currentValue = args.Column.GetValue(args.Data);
            Console.WriteLine($"currentValue: {currentValue}");

            var previousValue = args.Column.GetValue(previousData);
            Console.WriteLine($"previousValue: {previousValue}");

            if (columnName != null && !currentValue.Equals(previousValue))
            {
                args.Attributes.Add("class", "rz-background-color-secondary-lighter");
            }
        }
    }
}
```
以上。