Create Custom Blazor TopMenu with Radzen Components based on dynamic menu generated by code

Blazor Component Code :sweat_smile:
name DataPageHeader.razor

@using System.Diagnostics.CodeAnalysis
@inject NavigationManager NavigationManager
@inject SmartErpWebApp.Chaced.SessionUser sessionChace;
@using SmartErpWebApp.Components.Classes;

<PageTitle>@(PageTitle)</PageTitle>

<div id="@UID" class="card text-white e-card  " style="{width: 100%;!important;}">
  <div class="card-header e-card-header ">
        @if (Edit) {
            <div class="row">
                <div class="col-sm-auto">
                    <RadzenIcon Icon="edit" />
                </div>
                <div class="col-md-11">
                    <h1>
                        @(PageTitle+ " edit ")
                    </h1>
                </div>
            </div>
            if (!IsLoaded){
                <div class="row">
                    <div class="col-md-auto">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                            </div>
                             <em>
                                The application is loading...
                            </em>
                    </div>
                </div>
            }
        }else if (Delete){
           <div class="row">
                <div class="col-sm-auto">
                    <RadzenIcon Icon="delete" />
                </div>
                <div class="col-md-11">
                    <h1>@(PageTitle+ " delete ")</h1>
                </div>
            </div>
            if (!IsLoaded){
                <div class="row">
                    <div class="col-md-auto">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                            </div>
                             <em>
                                The application is loading...
                            </em>
                    </div>
                </div>
            }
        }
        else{
            <div class="row flex-nowrap">
                <div class="col-auto">
                    <RadzenIcon Icon="list" />
                </div>          
                <div class="col-auto">
                    <h1>@(PageTitle+ " list ")</h1>
                </div>
                @if (IsLoaded)
                {
                    <div class="col-auto">
                        <RadzenMenu id=@UID_Menu  >
                            @if (IsLoaded)
                            {
                                    if (href != null) { 
                                    <RadzenMenuItem Text="New..." Icon="add" class="e-card-header-menu-item" Click="@DataPageHeader_OnAddEvent" @onclick:stopPropagation="true" />
                                    }
                            }
                            @if (TopMenu is not null)
                            {
                                @foreach (CostumRadzenMenuItem item in TopMenu)
                                { 
                                    <RadzenMenuItem Text=@(item.Text) Icon=@(item.Icon) class="e-card-header-menu-item" Path=@(item.Path) @onclick:stopPropagation="true" >
                                        @foreach (RadzenMenuItem subitem in item.subitems)
                                        {
                                           <RadzenMenuItem Text=@(subitem.Text) Path=@(subitem.Path) Icon=@(subitem.Icon)  class="e-card-header-menu-item"></RadzenMenuItem>
                                        }
                                    </RadzenMenuItem>
                                }
                            }
                        </RadzenMenu>
                    </div>
                }
            </div>
            @if (!IsLoaded)
            {
                <div class="row flex-nowrap">
                    <div class="col">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                        </div>
                        <em>
                            The application is loading...
                        </em>
                    </div>
                </div>
            }
        }
    </div>
</div>

<style>
    @css  {
        background: @BackGroundColor;
    }
    @css_Menu {
        background-color: @BackGroundColor;
    }
    @css_Menu_Text {
        color:white;
    }
    @css_Menu_Icon {
        color: white!important;
    }
</style>

@code {
    public string UID = $"xx-{Guid.NewGuid().ToString()}";
    public string UID_Menu = $"xx-{Guid.NewGuid().ToString()}";

    private string css => $"#{UID} .e-card-header";
    private string css_Menu => $"#{UID_Menu} .rz-navigation-item-wrapper";
    private string css_Menu_Text => $"#{UID_Menu} .rz-navigation-item-text";
    private string css_Menu_Icon => $"#{UID_Menu} .e-card-header-menu-item .rzi";

    [Parameter] 
    public string Color { get; set; } = "#ffffff";

    [Parameter] 
    public string BackGroundColor { get; set; } = "#396ff8";

    [Parameter] 
    public string PageTitle { get; set; } = "PageTitle";

    [Parameter] 
    public bool Edit { get; set; } = false;

    [Parameter] 
    public bool Delete { get; set; } = false;

    [Parameter] 
    public bool IsLoaded { get; set; }

    [Parameter] 
    public string? href { get; set; } = null;

    [Parameter,AllowNull]
    public List<CostumRadzenMenuItem>? TopMenu { get; set; }

    protected override void OnInitialized()
    {
        base.OnInitialized();
    }

    private void DataPageHeader_OnAddEvent()
    {
        try
        {
            NavigationManager.NavigateTo($@"{href}");
        }
        catch (Exception ex)
        {
            sessionChace.Messages.Add(new Chaced.Message(ex.Message));
        }
    }

}

class CostumRadzenMenuItem.cs

using Radzen.Blazor;

namespace SmartErpWebApp.Components.Classes;

public class CostumRadzenMenuItem : RadzenMenuItem
{
    public List<RadzenMenuItem> subitems = new List<RadzenMenuItem>();
    public bool Selected { get; set; }
}

usage :sweat_smile:

<DataPageHeader TopMenu="topMenus" PageTitle="Companies" href="companiesReplace/0" IsLoaded=@(companies != null) />
@code{
    private List<CostumRadzenMenuItem> topMenus =
    new List<CostumRadzenMenuItem>{
        new CostumRadzenMenuItem {
            Text="Linked",
            Icon="link",
            subitems = new List<RadzenMenuItem>(){ 
                new RadzenMenuItem {
                    Text="Companies Types",
                    Path="companiesTypes",
                    Icon="border_clear",
                },
                new RadzenMenuItem {
                    Text="Aagents",
                    Icon="support_agent",
                    Path="agents"
                }
            }
        }
        };
}
1 Like

I hope this code is useful for someone :wink:, accept any tips. Oops this is the result :
Images-Top-Menu

1 Like

To remove parent arrow-icon with no childs, modify DataPageHeader.razor

@using System.Diagnostics.CodeAnalysis
@inject NavigationManager NavigationManager
@inject SmartErpWebApp.Chaced.SessionUser sessionChace;
@using SmartErpWebApp.Components.Classes;

<PageTitle>@(PageTitle)</PageTitle>

<div id="@UID" class="card text-white e-card  " style="{width: 100%;!important;}">
  <div class="card-header e-card-header ">
        @if (Edit) {
            <div class="row">
                <div class="col-sm-auto">
                    <RadzenIcon Icon="edit" />
                </div>
                <div class="col-md-11">
                    <h1>
                        @(PageTitle+ " edit ")
                    </h1>
                </div>
            </div>
            if (!IsLoaded){
                <div class="row">
                    <div class="col-md-auto">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                            </div>
                             <em>
                                The application is loading...
                            </em>
                    </div>
                </div>
            }
        }else if (Delete){
           <div class="row">
                <div class="col-sm-auto">
                    <RadzenIcon Icon="delete" />
                </div>
                <div class="col-md-11">
                    <h1>@(PageTitle+ " delete ")</h1>
                </div>
            </div>
            if (!IsLoaded){
                <div class="row">
                    <div class="col-md-auto">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                            </div>
                             <em>
                                The application is loading...
                            </em>
                    </div>
                </div>
            }
        }
        else{
            <div class="row flex-nowrap">
                <div class="col-auto">
                    <RadzenIcon Icon="list" />
                </div>          
                <div class="col-auto">
                    <h1>@(PageTitle+ " list ")</h1>
                </div>
                @if (IsLoaded)
                {
                    <div class="col-auto">
                        <RadzenMenu id=@UID_Menu  >
                            @if (IsLoaded)
                            {
                                /* Load New button if is load object or list of object */ 
                                if (href != null) { 
                                    <RadzenMenuItem Text="New..." Icon="add" class="e-card-header-menu-item" Click="@DataPageHeader_OnAddEvent" @onclick:stopPropagation="true" />
                                }
                            }
                            @if (TopMenu != null)
                            {
                                /* Load TopMenu if exist */ 
                                @foreach (CostumRadzenMenuItem item in TopMenu)
                                {
                                    @if (item.subitems != null)
                                    {
                                        /* Load subitems if exixts parent menu */
                                        <RadzenMenuItem Text=@(item.Text) Icon=@(item.Icon) class="e-card-header-menu-item" Path=@(item.Path) @onclick:stopPropagation="true"  >                                        
                                            @foreach (RadzenMenuItem subitem in item.subitems)
                                            {
                                                <RadzenMenuItem Text=@(subitem.Text) Path=@(subitem.Path) Icon=@(subitem.Icon)  class="e-card-header-menu-item"></RadzenMenuItem>
                                            }
                                        </RadzenMenuItem>
                                    }
                                    else {
                                        /* To avoid the creation off combo icon */
                                        <RadzenMenuItem Text=@(item.Text) Icon=@(item.Icon) class="e-card-header-menu-item" Path=@(item.Path) @onclick:stopPropagation="true" />
                                    }
                                }
                            }
                        </RadzenMenu>
                    </div>
                }
            </div>
            @if (!IsLoaded)
            {
                <div class="row flex-nowrap">
                    <div class="col">
                        <div class="spinner-border spinner-border-sm text-light" role="status">
                        </div>
                        <em>
                            The application is loading...
                        </em>
                    </div>
                </div>
            }
        }
    </div>
</div>

<style>
    @css  {
        background: @BackGroundColor;
    }
    @css_Menu {
        background-color: @BackGroundColor;
    }
    @css_Menu_Text {
        color:white;
    }
    @css_Menu_Icon {
        color: white!important;
    }
    @css_SubMenu_Icon {
        display:none!important;
    }
</style>

@code {
    public string UID = $"xx-{Guid.NewGuid().ToString()}";
    public string UID_Menu = $"xx-{Guid.NewGuid().ToString()}";

    private string css => $"#{UID} .e-card-header";
    private string css_Menu => $"#{UID_Menu} .rz-navigation-item-wrapper";
    private string css_Menu_Text => $"#{UID_Menu} .rz-navigation-item-text";
    private string css_Menu_Icon => $"#{UID_Menu} .e-card-header-menu-item .rzi";
    private string css_SubMenu_Icon => $"#{UID_Menu} .e-card-header-menu-item .rzi .rz-navigation-item-icon-children:empty";

    [Parameter] 
    public string Color { get; set; } = "#ffffff";

    [Parameter] 
    public string BackGroundColor { get; set; } = "#396ff8";

    [Parameter] 
    public string PageTitle { get; set; } = "PageTitle";

    [Parameter] 
    public bool Edit { get; set; } = false;

    [Parameter] 
    public bool Delete { get; set; } = false;

    [Parameter] 
    public bool IsLoaded { get; set; }

    [Parameter] 
    public string? href { get; set; } = null;

    [Parameter,AllowNull]
    public List<CostumRadzenMenuItem>? TopMenu { get; set; }

    protected override void OnInitialized()
    {
        base.OnInitialized();
    }

    private void DataPageHeader_OnAddEvent()
    {
        try
        {
            NavigationManager.NavigateTo($@"{href}");
        }
        catch (Exception ex)
        {
            sessionChace.Messages.Add(new Chaced.Message(ex.Message));
        }
    }

}


and declaration of menu set to subitems=null , that all

    private List<CostumRadzenMenuItem> topMenus =
    new List<CostumRadzenMenuItem>{
        new CostumRadzenMenuItem {
            Text="Companies",
            Icon="arrow_back",
            Path="/companies",
            subitems=null
            } };