[Blazor] With MudBlazor

MudBlazor๋ฅผ ํ™œ์šฉํ•œ UI ๊ตฌ์„ฑ ์ง€์‹์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

:pushpin: ํŽธ์˜์ƒ MudBlazor Template๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์„œ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค.

5๊ฐœ์˜ ์ข‹์•„์š”

๊ถ๊ธˆํ•˜๋„ค์š” ๊ธฐ๋Œ€

4๊ฐœ์˜ ์ข‹์•„์š”

์•—, ์ €๋„ ๊ด€์‹ฌ์žˆ์Šต๋‹ˆ๋‹ค. ใ…‹ใ…‹ใ…‹

3๊ฐœ์˜ ์ข‹์•„์š”

MudDialog

MudBlazor ๋ฌธ์„œ
https://mudblazor.com/components/dialog

Source code (GitHub)
https://github.com/ChoiHM/MB-MudDialogSample


๊ธฐ๋ณธ์ ์ธ ์‚ฌํ•ญ

Global ์„ค์ •

Shared>MainLayout.razor ํŒŒ์ผ์„ ์—ด์–ด์„œ ์ œ์ผ ์œ— ๋ถ€๋ถ„์„ ๋ด…๋‹ˆ๋‹ค.

@inherits LayoutComponentBase

<MudThemeProvider />
<MudDialogProvider /> @* <-- MudDialogProvider ์ธ์Šคํ„ด์Šค ์ •์˜ ๋ฐ Global setting *@
<MudSnackbarProvider />

์„ค์ •์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ์ฒด์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Dialog ํ˜ธ์ถœ์‹œ ๋ณ„๋‹ค๋ฅธ ์˜ต์…˜์„ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด Global ์„ค์ •์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.

<MudDialogProvider
    FullWidth="true"
    MaxWidth="MaxWidth.ExtraSmall"
    CloseButton="true"
    DisableBackdropClick="true"
    NoHeader="true"
    Position="DialogPosition.Center"
    CloseOnEscapeKey="true"
/>


Dialog ํ˜ธ์ถœ

1. Dialog ์ž…๋ ฅ๊ฐ’ ๋ฆฌํ„ด

์ด์ œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋ฒ„ํŠผ 2๊ฐœ๊ณผ Dialog ์ปดํฌ๋„ŒํŠธ๋„ 2๊ฐœ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.
ํŽ˜์ด์ง€๋Š” Index.razor๋ฅผ ๋Œ€์ถฉ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ 2๊ฐœ ์ถ”๊ฐ€ํ•˜๊ณ  onclick ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

  • Index.razor
@page "/"
@inject IDialogService _dialogService
@using MudDialogSample.Dialog;

<PageTitle>Index</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">Dialogํ…Œ์ŠคํŠธ</MudText>

<MudStack Row="true" Class="mb-5" Spacing="1">
    <MudButton Variant="Variant.Outlined" Size="Size.Small"
               @onclick="NewFolder">์ƒˆ ํด๋”</MudButton>

    <MudButton Variant="Variant.Outlined" Size="Size.Small"
               @onclick="NewFolderAsync">์ƒˆ ํด๋” Async</MudButton>

    <MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Info" StartIcon="@Icons.Material.Filled.CloudUpload"
               @onclick="Upload">์—…๋กœ๋“œ</MudButton>
</MudStack>

<MudText>ํด๋”๋ช…: @NewFolderName</MudText>

@code {
    private string NewFolderName = string.Empty;

    private void NewFolder()
    {
        // ๋ฆฌํ„ด๊ฐ’์ด ํ•„์š”ํ•˜๋‹ค๋ฉด Showํ•จ์ˆ˜๋กœ๋Š” ๋ฐ›์•„์˜ฌ ์ˆ˜ ์—†์–ด์š”!
        var dialog = _dialogService.Show<DlgNewFolder>("์ƒˆ ํด๋” ๋งŒ๋“ค๊ธฐ",
        new DialogOptions() { CloseOnEscapeKey = true });
        //var result = dialog.Result.Result;
    }

    private async void NewFolderAsync()
    {
        var dialog = await _dialogService.ShowAsync<DlgNewFolder>("์ƒˆ ํด๋” ๋งŒ๋“ค๊ธฐ",
        new DialogOptions() { CloseOnEscapeKey = true });
        var result = await dialog.Result;

        if (result == null || result.Canceled) { return; }
        if (result?.Data != null)
        {
            if (string.IsNullOrWhiteSpace(result.Data.ToString()))
            {
                return;
            }
            NewFolderName = result.Data.ToString();
            StateHasChanged();
        }
    }

    private async void Upload()
    {
    }
}

:pushpin: ShowAsync๋ฉ”์„œ๋“œ ์˜ค๋ฅ˜ ํ‘œ์‹œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

MudTemplate์„ ์ด์šฉํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด, ๊ตฌ๋ฒ„์ „์ด ์„ค์น˜๋œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ShowAsyncํ•จ์ˆ˜๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ, ์•„๋ž˜์™€ ๊ฐ™์ด ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
(์ €์˜ ๊ฒฝ์šฐ 6.0.13์ด ์„ค์น˜๋˜์–ด ์žˆ์œผ๋ฉฐ, 6.2.2๋กœ ์—…๋ฐ์ดํŠธ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.)


ํ”„๋กœ์ ํŠธ์— Dialog ํด๋”๋„ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜์—ฌ Dialog์šฉ๋„๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
'์ƒˆ ํด๋”'๋ฅผ ์œ„ํ•œ ํ•ญ๋ชฉ์ด๋ฏ€๋กœ DlgNewFolder.razor๋กœ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.



  • DlgNewFolder.razor ์†Œ์Šค์ฝ”๋“œ
<MudDialog DefaultFocus="DefaultFocus.FirstChild">
  <DialogContent>
      <MudForm ReadOnly="false">
          <MudTextField T="string" Label="ํด๋”๋ช…" @bind-Value="FolderName" Immediate="true" 
OnKeyDown="keydown"></MudTextField>
      </MudForm>
  </DialogContent>
  <DialogActions>
      <MudButton Color="Color.Primary" ButtonType="ButtonType.Submit"
OnClick="Submit">์ƒ์„ฑ</MudButton>
      <MudButton OnClick="Cancel">์ทจ์†Œ</MudButton>
  </DialogActions>
</MudDialog>

@code {
    [CascadingParameter] MudDialogInstance MudDialog { get; set; }
    [Parameter]
    public string FolderName { get; set; }

    void Submit() => MudDialog.Close(DialogResult.Ok(FolderName));
    void Cancel() => MudDialog.Cancel();

    private void keydown(KeyboardEventArgs e)
    {
        if (e.Key == "Enter")
        {
            MudDialog.Close(DialogResult.Ok(FolderName));
        }
    }
}

MudBlazor์—๋Š” FocusTrap์ด๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ด€๋ จ๋œ ์„ค๋ช…์€ MudBlazor ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.
๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…๋“œ๋ฆฌ์ž๋ฉด MudDialog์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ FocusTrap์ด ๋“ค์–ด๊ฐ€ ์žˆ์–ด์„œ

<MudDialog DefaultFocus="DefaultFocus.FirstChild">

์ด๋ ‡๊ฒŒ DefaultFocus๋ฅผ FirstChild๋กœ ์„ธํŒ…๋งŒ ํ•ด์ฃผ์…”๋„ ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ์— ์ž๋™์œผ๋กœ ํฌ์ปค์Šค๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฒซ๋ฒˆ์งธ ์š”์†Œ์ธ TextField์— onkeydown ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•จ์œผ๋กœ์จ, ์—”ํ„ฐํ‚ค์— ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋†จ์Šต๋‹ˆ๋‹ค.

<MudTextField T="string" Label="ํด๋”๋ช…" @bind-Value="FolderName" Immediate="true" 
OnKeyDown="keydown"></MudTextField>

์ž! ์ด์ œ ์‹คํ–‰ํ•ด์„œ ํŽ˜์ด์ง€๋ฅผ ๋„์šฐ๊ณ  โ€˜์ƒˆ ํด๋” Asyncโ€™ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋ด…๋‹ˆ๋‹ค.



์ฒ˜์Œ ํฌ์ปค์Šค๊ฐ€ TextField๋กœ ๊ฐ€ ์žˆ์„๊ฒ๋‹ˆ๋‹ค.
DotNetDev ์ž…๋ ฅ ํ›„ ์—”ํ„ฐ!


image

:stopwatch: ์‹œ๊ฐ„ ๊ด€๊ณ„์ƒ โ€œDialog๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ๋„˜๊ฒจ์ฃผ๊ธฐโ€ (์—…๋กœ๋“œ ๋ฒ„ํŠผ)๋Š” ๋‹ค์Œ ์‹œ๊ฐ„์— ์ถ”๊ฐ€ํ•˜๋„๋ก ํ• ๊ฒŒ์š”! :blush:

5๊ฐœ์˜ ์ข‹์•„์š”