Ligne 863 :
Ligne 863 :
|-
|-
| justify-space-around || justify-content: space-around;
| justify-space-around || justify-content: space-around;
|-
| flex-wrap || flex-wrap: wrap;
|}
|}
* [https://mudblazor.com/utilities/justify-content justify-content]
* [https://mudblazor.com/utilities/justify-content justify-content]
Version du 11 janvier 2025 à 11:04
Links
Shared/MainLayout.razor
@inherits LayoutComponentBase
<PageTitle > My Application</PageTitle >
<MudThemeProvider IsDarkMode ="true" Theme ="customTheme" />
<MudPopoverProvider />
<MudDialogProvider />
<MudSnackbarProvider />
<div >
<MudLayout >
<MudDrawer Open ="true" >
<MudDrawerHeader Class ="cursor-help mb-1 mx-auto" >
<MudTooltip Text ="@( $"Version {AssemblyVersion } " ) "
Placement ="Placement.Right"
Arrow ="true"
Duration ="1000" >
<MudText Typo ="Typo.h4" Color ="Color.Primary" > My Application</MudText >
</MudTooltip >
</MudDrawerHeader >
<NavMenu />
</MudDrawer >
<MudMainContent Class ="py-2" >
<MudContainer MaxWidth ="MaxWidth.Large" >
@ Body
</MudContainer >
</MudMainContent >
</MudLayout >
</div >
Shared/MainLayout.razor.css
::deep .mud-drawer-content {
background-image : linear-gradient (180deg , rgb (5 , 39 , 103 ) 0% , #3a0647 70% );
}
Shared/NavMenu.razor
<div >
<MudNavMenu >
<MudNavLink Href ="/"
Match ="NavLinkMatch.All"
Icon ="@ Icons.Material.Filled.Home "
IconColor ="Color.Primary" >
Home
</MudNavLink >
<MudNavLink Href ="/menu1"
Icon ="@ Icons.Material.Filled.Diversity1 "
IconColor ="Color.Secondary" >
Menu 1
</MudNavLink >
</MudNavMenu >
</div >
Shared/NavMenu.razor.css
::deep .mud-nav-item {
font-size : 0.9rem ;
padding : 0 1rem 0.5rem ;
}
::deep .mud-nav-item a {
height : 3rem ;
border-radius : 4px ;
display : flex;
align-items : center;
}
::deep .mud-nav-link:hover:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
}
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
color : inherit;
}
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled):hover:not (.mud-nav-link-disabled),
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled):focus-visible:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
}
Components
<MudButton Variant ="Variant.Filled"
StartIcon ="@ Icons.Material.Filled.Delete "
Color ="Color.Error" > Delete</MudButton >
<MudButton Href ="https://github.com/MudBlazor/MudBlazor"
Target ="_blank"
Variant ="Variant.Filled"
EndIcon ="@ Icons.Custom.Brands.GitHub "
Color ="Color.Primary" >
Link
</MudButton >
<MudButton Disabled ="@ processing "
OnClick ="Process"
Variant ="Variant.Filled"
Color ="Color.Primary" >
@ if (processing)
{
<MudProgressCircular Class ="ms-n1" Size ="Size.Small" Indeterminate ="true" />
<MudText Class ="ms-2" > Processing </MudText >
}
else
{
<MudText > Click me </MudText >
}
</MudButton >
@code {
private bool processing = false ;
async Task ProcessAsync ()
{
processing = true ;
await Task.Delay (2000 );
processing = false ;
}
}
Pages/MyPage.razor.cs
[Inject ]
private IDialogService DialogService { get ; set ; }
private void OnDisplayDialog ()
{
var dialogOptions = new DialogOptions () { CloseButton = true };
var parameters = new DialogParameters <MyDialog >
{
{ x => x.MyProperty, propertyValue }
};
DialogService.Show <MyDialog >("Title" , parameters , dialogOptions );
Dialogs/MyDialog.razor
<MudDialog >
<DialogContent >
</DialogContent >
<DialogActions >
<MudButton OnClick ="Cancel" > Cancel</MudButton >
<MudButton Color ="Color.Success" Variant ="Variant.Filled" OnClick ="Submit" > Ok</MudButton >
</DialogActions >
</MudDialog >
@code {
[Parameter ]
MyDto MyProperty { get ; set ; }
[CascadingParameter ]
MudDialogInstance MudDialog { get ; set ; }
void Submit () => MudDialog .Close (DialogResult .Ok (true ));
void Cancel () => MudDialog .Cancel ();
}
<MudIconButton Icon ="@ Icons.Material.Filled.DeleteForever "
Size ="Size.Small"
Color ="Color.Error"
aria-label ="delete"
OnClick ="@( () => OnDeleteAsync (@context.Id) ) "
Href ="@( $"items/{context .Id } " ) " />
<MudImage Src ="images/MyImage.svg"
Alt ="MyImage"
Width ="200"
Elevation ="10"
Class ="rounded-lg" />
<MudLink Href =""
Typo ="Typo.h3"
Underline ="Underline.None"
Color ="Color.Default"
Class ="purple-text text-lighten-3" > Text</MudLink >
<MudPaper MaxHeight ="200px" Class ="mt-1 overflow-y-auto border-solid border mud-border-error" >
<MudList T ="string"
Dense ="true"
Class ="mud-error-text" >
@ foreach (var error in Errors)
{
<MudListItem Text ="@ error " Icon ="@ Icons.Material.Filled.ErrorOutline " IconColor ="Color.Error" />
}
</MudList >
</MudPaper >
@code {
[Parameter ]
public IReadOnlyCollection <string > Errors { get ; set ; } = Array.Empty <string > ();
}
<MudMenu
Icon ="@ Icons.Material.Filled.MoreVert "
Size ="Size.Small"
AnchorOrigin ="Origin.CenterLeft"
TransformOrigin ="Origin.CenterRight" >
<MudMenuItem >
<MudIconButton
Icon ="@ Icons.Material.Filled.DeleteForever "
Size ="Size.Small"
Color ="Color.Error"
aria-label ="delete"
OnClick ="@( () => OnDeleteAsync (@context.Id) ) " />
</MudMenuItem >
</MudMenu >
Pages/MyPage.razor
<MudExpansionPanels MultiExpansion ="true" >
<MudExpansionPanel Text ="Panel One" >
Panel One Content
</MudExpansionPanel >
<MudExpansionPanel Text ="Panel Two" >
Panel Two Content
</MudExpansionPanel >
</MudExpansionPanels >
Pages/MyPage.razor
<MudButton Variant ="Variant.Filled" Color ="Color.Error" OnClick ="OnDeleteAsync" > Delete</MudButton >
<MudMessageBox @ref ="deleteItemDialog" Title ="Item deletion" >
<MessageContent >
Are you sure you want to delete the selected item?
</MessageContent >
<YesButton >
<MudButton Variant ="Variant.Filled" Color ="Color.Error" StartIcon ="@ Icons.Material.Filled.DeleteForever " > Delete</MudButton >
</YesButton >
</MudMessageBox >
Pages/MyPage.razor.cs
private async Task OnDeleteAsync ()
{
var dialogOptions = new DialogOptions
{
CloseButton = true ,
DisableBackdropClick = true
};
var result = await deleteItemDialog.ShowAsync (dialogOptions );
if (result != true )
{
return ;
}
<MudNavMenu >
<MudNavLink Href =""
Match ="NavLinkMatch.All"
Icon ="@ Icons.Material.Filled.Home "
IconColor ="Color.Primary" >
Home
</MudNavLink >
<MudNavLink Href ="menu1"
Icon ="@ Icons.Material.Filled.Diversity1 "
IconColor ="Color.Secondary" >
Menu 1
</MudNavLink >
</MudNavMenu >
<MudProgressCircular Color ="Color.Primary" Size ="Size.Small" Indeterminate ="true" />
<MudProgressCircular Color ="Color.Primary" Size ="Size.Small" Value ="@ progressValue " />
private double progressValue ;
Pages/MyPage.razor.cs
[Inject ]
private ISnackbar snackbar { get ; set ; } = default !;
snackbar.Add ("Success!!!" , Severity .Success );
snackbar.Add ($"Error!!!<br>Error message:<br>{operationStatus .ErrorMessage } " , Severity .Error );
Program.cs
builder.Services.AddMudServices (config =>
{
config .SnackbarConfiguration .PositionClass = Defaults .Classes .Position .BottomRight ;
config .SnackbarConfiguration .PreventDuplicates = true ;
config .SnackbarConfiguration .HideTransitionDuration = 100 ;
});
<MudText Typo ="Typo.h6"
Align ="Align.Center" >
Title
</MudText >
afficher <MudTable Items ="@ items "
SortLabel ="Sort By"
AllowUnsorted ="false" >
<HeaderContent >
<MudTh > Name</MudTh >
<MudTh >
<MudTableSortLabel SortBy ="new Func<Item, object>(x => x.Price)"
InitialDirection ="SortDirection.Descending" >
Price
</MudTableSortLabel >
</MudTh >
</HeaderContent >
afficher <MudTable @ref ="table"
ServerData ="ServerReloadAsync"
Hover ="true"
Loading ="@ isSearching "
LoadingProgressColor ="Color.Info"
Class ="flex-column" >
<ToolBarContent >
<MudFab Color ="Color.Primary"
StartIcon ="@ Icons.Material.Filled.Add "
Size ="Size.Small"
Href ="item/new" />
<MudTextField T ="string"
ValueChanged ="@( s => OnSearch (s) ) "
Placeholder ="Search"
Adornment ="Adornment.Start"
AdornmentIcon ="@ Icons.Material.Filled.Search "
IconSize ="Size.Medium"
Class ="mt-0 mx-16" >
</MudTextField >
</ToolBarContent >
<HeaderContent >
<MudTh Style ="text-align:right" > Name</MudTh >
<MudTh > </MudTh >
</HeaderContent >
<RowTemplate >
<MudTd DataLabel ="Name" Style ="text-align:right" > @ context.Name </MudTd >
<MudTd >
<MudMenu Icon ="@ Icons.Material.Filled.MoreVert "
Size ="Size.Small"
AnchorOrigin ="Origin.CenterLeft"
TransformOrigin ="Origin.CenterRight" >
<MudMenuItem >
<MudIconButton Icon ="@ Icons.Material.Filled.Edit "
Size ="Size.Small"
Color ="Color.Primary"
aria-label ="edit"
Href ="@( $"transaction/{context .Id } " ) " />
</MudMenuItem >
<MudMenuItem >
<MudIconButton Icon ="@ Icons.Material.Filled.DeleteForever "
Size ="Size.Small"
Color ="Color.Error"
aria-label ="delete"
OnClick ="@( () => OnDeleteAsync (context.Id) ) " />
</MudMenuItem >
</MudMenu >
</MudTd >
</RowTemplate >
<NoRecordsContent >
<MudText > No matching items found</MudText >
</NoRecordsContent >
<LoadingContent >
<MudText > Loading...</MudText >
</LoadingContent >
<PagerContent >
<MudTablePager PageSizeOptions ="new int[] { 10 }"
HorizontalAlignment ="HorizontalAlignment.Left"
HideRowsPerPage ="true" />
</PagerContent >
</MudTable >
afficher private bool isSearching ;
private async Task <TableData <ItemResponse >> ServerReloadAsync (TableState state , CancellationToken cancellationToken )
{
ArgumentNullException.ThrowIfNull (state );
errors.Clear ();
isSearching = true ;
var query = itemQueryBuildService.BuildQuery (searchText , state .Page + 1 , state .PageSize );
var result = await itemClient.GetPagedAsync (query , CancellationToken .None );
TableData <ItemResponse > data ;
if (!result.IsValid)
{
errors.AddRange (result .ErrorMessages );
data = new TableData <ItemResponse > { Items = Enumerable.Empty <ItemResponse >() };
}
else
{
data = new TableData <ItemResponse >
{
TotalItems = result.Result.TotalCount,
Items = result.Result.Response
};
}
isSearching = false ;
return data;
}
private void OnSearch (string searchText )
{
this .searchText = searchText;
table.ReloadServerData ();
}
private async Task OnDeleteAsync (uint ItemId )
{
var dialogOptions = new DialogOptions { CloseButton = true };
var result = await deleteItemDialog.Show (dialogOptions );
if (result != true )
{
return ;
}
var operationStatus = await itemClient.DeleteItemAsync (itemId , CancellationToken .None );
if (operationStatus.Success)
{
snackbar.Add ("The item has been well deleted" , Severity .Success );
}
else
{
snackbar.Add (
$"The item has not been deleted.<br>Error message:<br>{operationStatus .ErrorMessage } " ,
Severity .Error );
}
}
RowEditCommit and async method
afficher <MudTable
RowEditCommit ="SaveChangesAsync" >
afficher private async void SaveChangesAsync (object element )
{
var operationStatus = await itemClient
.UpdateItemAsync (item .Id , item , CancellationToken .None );
StateHasChanged ();
<MudTabs Elevation ="2" Rounded ="true" Centered ="true" ApplyEffectsToContainer ="true" PanelClass ="pa-6" >
<MudTabPanel Text ="Tab text 1" > ...</MudTabPanel >
<MudTabPanel Text ="Tab text 2" > ...</MudTabPanel >
</MudTabs >
<MudTooltip Text ="Delete" Placement ="Placement.Right" Arrow ="true" Duration ="1000" >
<MudIconButton Icon ="@ Icons.Material.Filled.Delete " />
</MudTooltip >
Pages/ItemForm.razor
@ if (Item is not null )
{
<MudCard >
<MudForm @ref ="@ form " Model ="@ Item " Validation ="@( itemViewModelValidator.ValidateValue ) " >
<MudCardContent >
<MudTextField
@bind-Value ="Item.Name"
For ="@( () => Item.Name ) "
Label ="Name"
DebounceInterval ="500"
AutoFocus ="true" />
</MudCardContent >
</MudForm >
<MudCardActions >
<MudButton
Variant ="Variant.Filled"
Color ="Color.Default"
Class ="ml-auto mr-2"
OnClick ="@ CancelRequest " >
Cancel
</MudButton >
<MudButton
Variant ="Variant.Filled"
Color ="Color.Primary"
Class ="mr-4"
OnClick ="@ SubmitAsync " >
Save
</MudButton >
</MudCardActions >
</MudCard >
}
Pages/ItemForm.razor.cs
[Parameter ]
public CreateUpdateItemQuery Item { get ; set ; } = default !;
[Parameter ]
public EventCallback <bool > ValidationResult { get ; set ; }
[Parameter ]
public EventCallback CancelRequest { get ; set ; }
private IForm form = default !;
private readonly CreateUpdateItemQueryValidator itemQueryValidator = new ();
private Task SubmitAsync () => ValidationResult .InvokeAsync (form .IsValid );
afficher Validators/CreateUpdateItemQueryValidator.cs
public class CreateUpdateItemQueryValidator : AbstractValidator <CreateUpdateItemQuery >
{
public CreateUpdateItemQueryValidator ()
{
RuleFor (x => x .Name ).NotEmpty ();
}
public Func<object , string , Task<IEnumerable<string >>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync (ValidationContext <CreateUpdateItemQuery >.CreateWithOptions (
(CreateUpdateItemQuery )model, x => x.IncludeProperties (propertyName )));
return result.IsValid
? (IEnumerable <string >)Array .Empty <string >()
: result.Errors .Select (e => e .ErrorMessage );
};
}
Pages/CreateItem.razor
<ItemForm
Item ="@ item "
ValidationResult ="@( async (success) => await ValidationResultAsync (success) ) "
CancelRequest ="@( () => NavigationManager.NavigateTo ( "item" ) ) " />
afficher Pages/CreateItem.razor.cs
private async Task ValidationResultAsync (bool isValid )
{
errors.Clear ();
if (!isValid)
{
return ;
}
var operationStatus = await ItemClient.CreateAsync (item , CancellationToken .None );
if (operationStatus.Success)
{
Snackbar.Add ("The item has been well created" , Severity .Success );
NavigationManager.NavigateTo ("item" );
}
else
{
errors.AddRange (operationStatus .Errors .SelectMany (x => x .Value ));
}
}
Add the package FluentValidation to use it.
<MudTextField @ref ="searchTextField"
T ="string"
ValueChanged ="@( s => OnSearch (s) ) "
Placeholder ="Search"
Adornment ="Adornment.Start"
AdornmentIcon ="@ Icons.Material.Filled.Search "
IconSize ="Size.Medium"
Clearable ="true"
Class ="mt-0 mx-16" >
<MudField Label ="Type" Class ="mt-2" Variant ="Variant.Text" InnerPadding ="false" >
<MudRadioGroup @bind-Value ="item.Type" >
<MudRadio Value ="@( "type1" ) " Color ="Color.Primary" > Type1</MudRadio >
<MudRadio Value ="@( "type2" ) " Color ="Color.Primary" > Type2</MudRadio >
</MudRadioGroup >
</MudField >
<MudNumericField
@bind-Value ="item.Quantity"
Label ="Quantity"
Variant ="Variant.Text"
Min ="1"
HideSpinButtons ="true" />
<MudDatePicker Label ="Date"
@bind-Date ="item.Date"
Culture ="@ frCulture " />
@code {
CultureInfo frCulture = CultureInfo.GetCultureInfo ("fr-FR" );
}
<MudTimePicker Label ="Time"
@bind-Time ="item.Time"
Culture ="@ frCulture " />
@code {
CultureInfo frCulture = CultureInfo.GetCultureInfo ("fr-FR" );
}
<MudAutocomplete
T ="MyNamespace.CurrencyResponse"
Label ="Currency"
@bind-Value ="item.Currency"
SearchFuncWithCancel ="@ SearchCurrenciesByCodeAsync "
ToStringFunc ="@( x => x == null ? null : x.Code ) "
Strict ="false"
ShowProgressIndicator ="true" >
<BeforeItemsTemplate >
<MudText Class ="px-4 py-1" > 3 characters min.</MudText >
</BeforeItemsTemplate >
<NoItemsTemplate >
<MudText Align ="Align.Center" Class ="px-4 py-1" >
No matching currencies found
</MudText >
</NoItemsTemplate >
private async Task <IEnumerable <CurrencyResponse >> SearchCurrenciesByCodeAsync (string value , CancellationToken cancellationToken )
=> await CurrencyClient .GetCurrenciesByCodeAsync (value , cancellationToken );
private async Task <IEnumerable <CurrencyResponse >> SearchCurrenciesByCodeAsync (string value )
{
var currencies = await CurrencyClient.GetAllAsync ();
return string .IsNullOrEmpty (value )
? (IEnumerable <CurrencyResponse >)currencies
: currencies.Where (x => x .Code .StartsWith (value , StringComparison .InvariantCultureIgnoreCase ));
}
<MudSelect @bind-Value ="logLevel" Label ="Log level" >
@ foreach (LogLevel logLevel in Enum.GetValues (typeof (LogLevel )))
{
<MudSelectItem Value ="@ logLevel " > @ logLevel .ToString () </MudSelectItem >
}
</MudSelect >
<MudSelect
T ="Namespace.Item"
@bind-Value ="@ selectedItem "
Label ="Item"
AnchorOrigin ="Origin.BottomCenter" >
@ foreach (var item in items )
{
<MudSelectItem Value ="@ item " > @ item.Description </MudSelectItem >
}
</MudSelect >
<MudSelect @bind-Value ="@ selectedItem " Label ="Item" >
<MudSelectItem Value ="@( "Item1 " ) " > Item1</MudSelectItem >
<MudSelectItem Value ="@( "Item2 " ) " > Item2</MudSelectItem >
</MudSelect >
private readonly List <Item > items = new ();
private Item selectedItem = default !;
protected override async Task OnInitializedAsync ()
{
var item = items.FirstOrDefault (x => x .Description == "best item" );
if (item is not null )
{
selectedItem = item;
}
StateHasChanged ();
}
<MudFileUpload T ="IReadOnlyList<IBrowserFile>"
Accept =".pdf, .csv"
AppendMultipleFiles
MaximumFileCount ="@( int .MaxValue) "
FilesChanged ="UploadFileAsync"
Class ="mt-0" >
<ActivatorContent >
<MudButton Variant ="Variant.Filled"
Color ="Color.Primary"
StartIcon ="@ Icons.Material.Filled.UploadFile " >
Load
</MudButton >
</ActivatorContent >
</MudFileUpload >
private async Task UploadFileContentAsync (IReadOnlyList <IBrowserFile > files )
{
var filesTooBig = files.Where (x => x .Size > 512000 ).ToArray ();
errors.AddRange (filesTooBig .Select (GetFileTooBigErrorMessage ));
var tasks = files
.Except (filesTooBig )
.Select (
async x => new
{
name = x .Name ,
content = await GetFileContentAsync (x )
});
var fileContents = await Task.WhenAll (tasks );
static async Task <byte []> GetFileContentAsync (IBrowserFile file )
{
using var stream = file.OpenReadStream ();
using var memoryStream = new MemoryStream ();
await stream.CopyToAsync (memoryStream );
return memoryStream.ToArray ();
}
}
<MudIcon Icon ="@ Icons.Material.Filled.Sell " Title ="Favorite" Color ="Color.Primary" Size ="Size.Small" />
<MudIconButton Icon ="@ Icons.Material.Filled.Home " />
<MudIconButton Icon ="@ myIcon " />
@code
{
string myIcon = MudBlazor.Icons.Material.Filled.Home;
}
CSS utilities
Code
Description
m p
margin padding
t b r l
top bottom right left
x
left and right
y
top and bottom
a
all 4 sides
0 1 n1 auto
0 4px -4px auto
<MudPaper Class ="pa-4 mr-16" >
Class
Property
d-block
display: block;
d-inline
display: inline;
d-none
display: none;
Class
Property
d-flex
display: flex;
justify-center
justify-content: center;
justify-space-around
justify-content: space-around;
flex-wrap
flex-wrap: wrap;
Code
Description
border
border-width: 1px;
border-solid
border-style: solid;
mud-border-primary
<MudPaper Class ="cursor-pointer" > Hand with finger raised</MudPaper >
<MudPaper Class ="cursor-help" > Question mark</MudPaper >
<MudPaper Color ="Color.Primary" >
Color enum
</MudPaper >
<MudPaper Class ="mud-info mud-secondary-text" >
CSS and theme colors. background: theme info blue; color: theme secondary pink
</MudPaper >
<MudPaper Style ="@( $"color:{theme .Palette .Dark } ; background:{theme .Palette .Warning } ;" ) " >
C# and theme colors
</MudPaper >
<MudPaper Class ="blue lighten-4 red-text text-darken-4" >
CSS and material colors background: blue lighten4; color: red darken4
</MudPaper >
<MudPaper Style ="@( $"color:{Colors .Blue .Lighten4 } ; background:{Colors .Red .Darken4 } ;" ) " >
C# and material colors
</MudPaper >
<span style ="color: var(--mud-palette-warning);" > C# and CSS colors</span >
@code {
private MudTheme theme = new MudTheme ();
}
Shared/MainLayout.razor
<MudThemeProvider IsDarkMode ="true" Theme ="customTheme" />
@code {
MudTheme customTheme = new MudTheme
{
PaletteDark = new PaletteDark
{
Background = "#222"
},
LayoutProperties = new LayoutProperties
{
DrawerWidthLeft = "160px"
}
};
}
wwwroot/css/theme.css
.mud-icon-default {
color : var (--mud-palette-primary);
}
first tag of a component has to be an HTML tag (<div> ), not a MudBlazor tag.
use ::deep .my-class when class is set on a MudBlazor component
you may need to refresh the browser cache
MyPage.razor
<div >
<MudText Typo ="Typo.h1" id ="title1" > @ name </MudText >
<h2 id ="title2" > @ name </h2 >
<div >
MyPage.razor.css
::deep title1 { }
title2 { }
Build component in the code-behind
MyPage.razor
<MudTd DataLabel ="Type" >
@ GetIconFromType (context .Type )
</MudTd >
MyPage.razor.cs
private static RenderFragment GetIconFromType (string type )
=> builder =>
{
builder.OpenComponent <MudIcon >(0 );
builder.AddAttribute (1 , "Title" , type );
builder.AddAttribute (2 , "Icon" , @Icons .Material .Filled .Money );
builder.AddAttribute (3 , "Color" , type switch
{
"deposit" => Color .Success ,
"withdrawal" => Color .Warning ,
"charge" => Color .Error ,
_ => throw new NotSupportedException ($"The type '{type } ' is not supported." )
});
builder.CloseComponent ();
};
New project from template
dotnet new install MudBlazor.Templates
dotnet new mudblazor --help
dotnet new mudblazor --host server --output MudBlazor
Remove HTTPS
Properties/launchSettings.json
{
"iisSettings" : {
"iisExpress" : {
"applicationUrl" : "http://localhost:5000" ,
}
} ,
"profiles" : {
"MudBlazorThemeManager" : {
"applicationUrl" : "http://localhost:5000" ,
.NET 7
By default the template set the project to .NET 6
MYproject.csproj
<Project Sdk ="Microsoft.NET.Sdk.Web" >
<PropertyGroup >
<TargetFramework > net7.0</TargetFramework >
.vscode/launch.json
{
"configurations" : [
{
"program" : "${workspaceFolder}/bin/Debug/net7.0/MyProject.dll" ,
_Layout.cshtml
Remove _Layout.cshtml
afficher _Host.cshtml
@page "/"
@using Microsoft.AspNetCore.Components.Web
@ namespace MyApp.Pages
@ addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang ="en" >
<head >
<meta charset ="utf-8" />
<meta name ="viewport" content ="width=device-width, initial-scale=1.0" />
<base href ="~/" />
<link href ="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel ="stylesheet" />
<link href ="_content/MudBlazor/MudBlazor.min.css" rel ="stylesheet" />
<link rel ="stylesheet" href ="MyApp.styles.css" />
<component type ="typeof(HeadOutlet)" render-mode ="ServerPrerendered" />
</head >
<body >
<component type ="typeof(App)" render-mode ="ServerPrerendered" />
<div id ="blazor-error-ui" >
<environment include ="Staging,Production" >
An error has occurred. This application may no longer respond until reloaded.
</environment >
<environment include ="Development" >
An unhandled exception has occurred. See browser dev tools for details.
</environment >
<a href ="" class ="reload" > Reload</a >
<a class ="dismiss" > 🗙</a >
</div >
<script src ="_framework/blazor.server.js" > </script >
<script src ="_content/MudBlazor/MudBlazor.min.js" > </script >
</body >
</html >
afficher Shared/MainLayout.razor
<MudThemeProvider IsDarkMode ="true" Theme ="customTheme" />
@code {
MudTheme customTheme = new MudTheme
{
LayoutProperties = new LayoutProperties
{
DrawerWidthLeft = "160px"
}
};
}
afficher Shared/MainLayout.razor.css
::deep .mud-drawer-content {
background-image : linear-gradient (180deg , rgb (5 , 39 , 103 ) 0% , #3a0647 70% );
}
afficher Shared/NavMenu.razor.css
::deep .mud-nav-item {
font-size : 0.9rem ;
padding : 0 1rem 0.5rem ;
}
::deep .mud-nav-item a {
height : 3rem ;
border-radius : 4px ;
display : flex;
align-items : center;
}
::deep .mud-nav-link:hover:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
}
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
color : inherit;
}
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled):hover:not (.mud-nav-link-disabled),
::deep .mud-navmenu.mud-navmenu-default .mud-nav-link.active:not (.mud-nav-link-disabled):focus-visible:not (.mud-nav-link-disabled) {
background-color : rgba (255 ,255 ,255 ,0.1 );
}
Already existing project
dotnet add package MudBlazor
_Imports.razor
@using MudBlazor
Pages/_Host.cshtml
<link href ="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel ="stylesheet" />
<link href ="_content/MudBlazor/MudBlazor.min.css" rel ="stylesheet" />
<script src ="_content/MudBlazor/MudBlazor.min.js" > </script >
Program.cs
builder.Services.AddMudServices ();
Shared/MainLayout.razor
<MudThemeProvider />
<MudPopoverProvider />
<MudDialogProvider />
<MudSnackbarProvider />