0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Fluent UI Blazorのデータグリッドでデータの追加・削除・編集、まとめて操作を行う

Last updated at Posted at 2025-02-19

1. はじめに

Fluent UI Blazorのデータグリッドでデータの追加・削除・編集、まとめて操作を行う方法をご紹介します。

image.png

2. 使用コンポーネント

本記事ではMicrosoft.FluentUI.AspNetCore.Componentsを使用します。

上記の記事の導入方法で指定するコンポーネント名をMicrosoft.FluentUI.AspNetCore.Componentsに変更し実施いただくことで利用できます。

3. ソースコード

本ソースコードは、プロジェクトテンプレートBlazor Web Appに含まれるServerProject\Components\Pages\Weather.razorの実装を元にしています。

@page "/weather"
@rendermode CustomRenderingMode.InteractiveServerWithoutPrerendering
 @using Microsoft.FluentUI.AspNetCore.Components

<PageTitle>Weather</PageTitle>

<h1>Weather</h1>

<FluentStack Orientation="Orientation.Horizontal" Width="1600px">
    <FluentNumberField Min="-20" Max="50" @bind-Value="@(temperatureCNum)" Style="width:100px" /><FluentButton Appearance="Appearance.Accent" OnClick="Create">
        追加
    </FluentButton>

    <FluentButton Appearance="Appearance.Accent" OnClick="@(x => Update(forecasts!.Where(x => x.Selected).ToList()))" Disabled="@(forecasts!.Where(x => x.Selected).ToList().Count == 0)">
        更新
    </FluentButton>

    <FluentButton Appearance="Appearance.Accent" OnClick="@(x => Delete(forecasts!.Where(x => x.Selected).ToList()))" Disabled="@(forecasts!.Where(x => x.Selected).ToList().Count == 0)">
        削除
    </FluentButton>
</FluentStack>
<FluentStack Orientation="Orientation.Horizontal" Width="1200px">
    <div style="overflow-x: auto;">
        <FluentDataGrid Style="height: 700px;width:1200px;overflow:auto;" TGridItem="WeatherRecord" Items="@forecasts?.OrderBy(x => x.weather.Date).AsQueryable()" GenerateHeader="GenerateHeaderOption.Sticky">
            <ChildContent>
                <SelectColumn TGridItem="WeatherRecord"
							SelectMode="DataGridSelectMode.Multiple"
							SelectFromEntireRow="true"
							Property="@(e => e.Selected)"
							OnSelect="@(e => e.Item.Selected = e.Selected)"
							SelectAll="@(forecasts?.All(p => p.Selected))"
							SelectAllChanged="@(all => forecasts?.ToList().ForEach(p => p.Selected = (all == true)))" />
                <PropertyColumn Title="Date" Property="@(c => DateTimeToString(c.weather.Date.ToLocalTime()))" Align="Align.Start"/>
                <PropertyColumn Title="℃" Property="@(c => c.weather.TemperatureC)" Align="Align.Start" />
                <PropertyColumn Title="℉" Property="@(c => c.weather.TemperatureF)" Align="Align.Start"/>
                <PropertyColumn Title="Summary" Property="@(c => GetSummariesStr(c.weather.Summary))" Align="Align.Start" />

            </ChildContent>
            <EmptyContent>
                <FluentLabel>&nbsp; 該当データがありません。</FluentLabel>
            </EmptyContent>
            <LoadingContent>
                <FluentStack Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center">
                    <FluentProgressRing Width="120px" />
                </FluentStack>
            </LoadingContent>
        </FluentDataGrid>
    </div>
</FluentStack>
@code {
    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public int TemperatureF => (32 + (int)(TemperatureC / 0.5556));
        public int Summary => GetSummaries(TemperatureC);
    }

    public record WeatherRecord
    {
        public WeatherForecast? weather { get; set; }
        public bool Selected { get; set; } = false;
    }

    public enum summariesEnum : uint
    {
        Freezing = 1,
        Bracing,
        Chilly,
        Cool,
        Mild,
        Warm,
        Balmy,
        Hot,
        Sweltering,
        Scorching,
        Unknown = 100,
    }

    List<WeatherRecord>? forecasts = new List<WeatherRecord>();
    int temperatureCNum { get; set; } = 0;
    //表示用データを生成する
    protected override async Task OnInitializedAsync()
    {
        if (!forecasts.Any())
        {
            for (int i = 0; i < 10; i++)
            {
                WeatherForecast tempWeather = new WeatherForecast()
                    {
                        Date = DateTime.UtcNow.AddDays(i),
                        TemperatureC = Random.Shared.Next(-20, 55),
                    };
                WeatherRecord temp = new WeatherRecord() { weather = tempWeather, Selected = false };
                forecasts.Add(temp);
            }
        }
    }

    //Summary判定用関数
    public static int GetSummaries(int temperatureC)
    {
        if (-20 <= temperatureC && temperatureC <= -1)
        {
            //Freezing
            return 1;
        }

        if (0 <= temperatureC && temperatureC <= 5)
        {
            //Bracing
            return 2;
        }

        if (6 <= temperatureC && temperatureC <= 10)
        {
            //Chilly
            return 3;
        }

        if (11 <= temperatureC && temperatureC <= 15)
        {
            //Cool
            return 4;
        }

        if (16 <= temperatureC && temperatureC <= 20)
        {
            //Mild
            return 5;
        }

        if (21 <= temperatureC && temperatureC <= 25)
        {
            //Warm
            return 6;
        }

        if (26 <= temperatureC && temperatureC <= 30)
        {
            //Balmy
            return 7;
        }

        if (31 <= temperatureC && temperatureC <= 35)
        {
            //Hot
            return 8;
        }

        if (36 <= temperatureC && temperatureC <= 45)
        {
            //Sweltering
            return 9;
        }

        if (46 <= temperatureC && temperatureC <= 55)
        {
            //Scorching
            return 10;
        }
        //Unknown
        return 100;
    }

    //Summary表示用関数
    string GetSummariesStr(int summary)
    {
        switch (summary)
        {
            case 1:
                return "Freezing";
            case 2:
                return "Bracing";
            case 3:
                return "Chilly";
            case 4:
                return "Cool";
            case 5:
                return "Mild";
            case 6:
                return "Warm";
            case 7:
                return "Balmy";
            case 8:
                return "Hot";
            case 9:
                return "Sweltering";
            case 10:
                return "Scorching";
            default:
                return "Unknown";
        }
    }

    //Dateのフォーマット用関数
    string DateTimeToString(DateTime? dateTime)
    {
        if (dateTime == null || dateTime == DateTime.MinValue || dateTime == DateTime.MinValue.ToLocalTime())
        {
            return string.Empty;
        }
        return dateTime?.ToString("yyyy-MM-dd") ?? string.Empty;
    }

    //追加処理
    async Task Create()
    {
        WeatherForecast tempWeather = new WeatherForecast()
            {
                Date = DateTime.UtcNow,
                TemperatureC = (int)temperatureCNum,
            };
        WeatherRecord temp = new WeatherRecord() { weather = tempWeather, Selected = false };
        forecasts.Add(temp);
    }

    //編集処理
    async Task Update(List<WeatherRecord> weathers)
    {
        foreach (var weather in weathers)
        {
            forecasts.Remove(weather);
            WeatherForecast tempWeather = new WeatherForecast()
                {
                    Date = weather.weather.Date,
                    TemperatureC = (int)temperatureCNum,
                };
            WeatherRecord temp = new WeatherRecord() { weather = tempWeather, Selected = false };
            forecasts.Add(temp);
        }
    }

    //削除処理
    async Task Delete(List<WeatherRecord> weathers)
    {
        foreach (var weather in weathers)
        {
            forecasts.Remove(weather);
        }
    }
}

4. 解説

4.1 複数操作

                <SelectColumn TGridItem="WeatherRecord"
							SelectMode="DataGridSelectMode.Multiple"
							SelectFromEntireRow="true"
							Property="@(e => e.Selected)"
							OnSelect="@(e => e.Item.Selected = e.Selected)"
							SelectAll="@(forecasts?.All(p => p.Selected))"

SelectColumnでチェックボックスの表示・選択状態の取得を行っています。
全選択用チェックボックスはヘッダーに生成されます。

プロパティ 説明
TGridItem SelectColumnが扱う型を指定する
SelectMode チェックボックスが単一選択か複数選択かを指定する
SelectFromEntireRow チェックボックスの全選択に対応するかを指定する
Property 選択状態を指定された値にバインドする
OnSelect チェックされたときの動作を指定する
SelectAll 全選択が行われているかをチェックする

4.2 追加

image.png

image.png

    <FluentButton Appearance="Appearance.Accent" OnClick="Create">
        追加
    </FluentButton>
    
    <FluentNumberField Min="-20" Max="50" @bind-Value="@(temperatureCNum)" Style="width:100px"/>
    async Task Create()
    {
        WeatherForecast tempWeather = new WeatherForecast()
            {
                Date = DateTime.UtcNow,
                TemperatureC = (int)temperatureCNum,
            };
        WeatherRecord temp = new WeatherRecord() { weather = tempWeather, Selected = false };
        forecasts.Add(temp);
    }

FluentNumberFieldで指定したTemperatureC(℃)を実行時の日時で登録します。
TemperatureF(℉)SummaryTemperatureC(℃)を元に算出します。

4.3 更新

image.png

image.png

    <FluentButton Appearance="Appearance.Accent" OnClick="@(x => Update(forecasts!.Where(x => x.Selected).ToList()))" Disabled="@(forecasts!.Where(x => x.Selected).ToList().Count == 0)">
        更新
    </FluentButton>

    <FluentNumberField Min="-20" Max="50" @bind-Value="@(temperatureCNum)" Style="width:100px"/>
    async Task Update(List<WeatherRecord> weathers)
    {
        foreach (var weather in weathers)
        {
            forecasts.Remove(weather);
            WeatherForecast tempWeather = new WeatherForecast()
                {
                    Date = weather.weather.Date,
                    TemperatureC = (int)temperatureCNum,
                };
            WeatherRecord temp = new WeatherRecord() { weather = tempWeather, Selected = false };
            forecasts.Add(temp);
        }
    }

チェックボックスで選択した項目をFluentNumberFieldで指定したTemperatureC(℃)を元に更新します。
チェックボックスでなにも選択していない場合は、Disabledによって更新ボタンが無効になります。

4.4 削除

image.png

image.png

    <FluentButton Appearance="Appearance.Accent" OnClick="@(x => Delete(forecasts!.Where(x => x.Selected).ToList()))" Disabled="@(forecasts!.Where(x => x.Selected).ToList().Count == 0)">
    async Task Delete(List<WeatherRecord> weathers)
    {
        foreach (var weather in weathers)
        {
            forecasts.Remove(weather);
        }
    }

チェックボックスで選択した項目を削除します。
チェックボックスでなにも選択していない場合は、Disabledによって削除ボタンが無効になります。

5. おわりに

Fluent UI Blazorを使用することで、様々なデータの操作を行うことができるデータグリッドを簡単に実装することができました。
Fluent UI Blazorに関する以下の記事も見ていただけると嬉しいです!

6. 参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?