Which MenuItem has been clicked?

In my project I have a Blazor.Navigations.SfMenu.  A List<MenuItem> is dynamically built and assigned to SfMenu.Items in the OnAfterRenderAsync(bool firstRender) event when firstRender = true.  The items displayed by our SfMenu can vary according to a variety of configuration parameters.  The menu structure can be 3 - 4 levels deep as some MenuItem objects have Lists of other MenuItem objects assigned to their MenuItem.Items properties.

Our SfMenu ItemSelected event references the following Callback:

     public  void onMenuClick(MenuEventArgs<MenuItemModel> args)
        {
            MenuItem itemClicked= MainMenuItems.Find(item => item.Id == args.Item.Id);
         }

The statement within this Callback that enables the MenuItem clicked to be resolved and referenced in the itemClicked variable works well if a top level menu entry is clicked.  However, if a menu entry that is 2 - 3 levels deep is clicked how do we resolve that and recover the source MenuItem clicked?  It would be useful if each MenuItem had a Parent property so you could "walk" cascading lists of MenuItems but there seems to be no way the Parent of a MenuItem can be determined.

Your advice would be appreciated.

Peter,

6 Replies 1 reply marked as answer

MK Mohan Kumar Ramasamy Syncfusion Team October 14, 2020 03:23 PM UTC

Hi Peter, 
 
We have checked your reported query, we can get the parent item using GetItemIndex method. Please refer below code snippets. 
 
div class="control-section"> 
    <div class="menu-control"> 
        <SfMenu Items="@menuItems" @ref="MenuObj"> 
            <MenuEvents ItemSelected="Selected" TValue="MenuItem"></MenuEvents> 
        </SfMenu> 
    </div> 
</div> 
@code{ 
 
    SfMenu<MenuItem> MenuObj; 
 
    private void Selected(MenuEventArgs<MenuItem> args) 
    { 
        var itemIndex = MenuObj.GetItemIndex(args.Item); 
        var item = menuItems.GetRange(itemIndex[0], 1); 
    } 
} 
 
For your reference, we have prepared a sample based on this, please refer below link. 
 
 
Please let us know, if you need any further assistance. 
 
Regards, 
Mohan kumar R 


Marked as answer

TT Todd Taylor May 11, 2022 06:31 PM UTC

Hello, 

Online support had directed me to this post which helped me to implement SfMenu for navigation.  I thought I would share my solution since in my case, referencing the index was not required. 

        BMP - SfMenu.png


The following code was added to NavMenu.razor 


@inject NavigationManager _navigationManager


<SfMenu Items="@menuItems" @ref="menuObj">

    <MenuEvents TValue="MenuItem" ItemSelected="itemSelected"></MenuEvents>

</SfMenu>


@code{

    SfMenu<MenuItem> menuObj;


    private void itemSelected(MenuEventArgs<MenuItem> args)

    {

        if(args.Item.Id == "11")

        {

            _navigationManager.NavigateTo("/ProcessDashboard");

        }

        if(args.Item.Id == "12")

        {

            _navigationManager.NavigateTo("/ProcessDiagram");

        }

        if(args.Item.Id == "2")

        {

            _navigationManager.NavigateTo("/BusinessAnalysis");

        }

        if(args.Item.Id == "3")

        {

            _navigationManager.NavigateTo("/ProcessItems/1");

        }

        if(args.Item.Id == "4")

        {

            _navigationManager.NavigateTo("/ProcoreProject");

        }

        if(args.Item.Id == "5")

        {

            _navigationManager.NavigateTo("/InitiativePortfolio");

        }

    }


     private List<MenuItem> menuItems = new List<MenuItem>

     {

        new MenuItem

        {

            Text = "Process View",

            Id = "1",

            Items = new List<MenuItem>()

            {

                new MenuItem { Text= "Matrix", Id = "11" },

                new MenuItem { Text= "Diagram", Id = "12" },

            }

        },

        new MenuItem

        {

            Text = "Business Anlaysis",

            Id = "2"

        },

        new MenuItem

        {

            Text = "Process Items",

            Id = "3"

        },

         new MenuItem

        {

            Text = "Project Upload",

            Id = "4"

        },

        new MenuItem

        {

            Text = "Initiatives",

            Id = "5"

        }

     };

}



YA YuvanShankar Arunagiri Syncfusion Team May 13, 2022 07:37 AM UTC

Hi Taylor,


Thanks for sharing the solution.


Regards,

YuvanShankar A



RB Rifat Burak Tozkoparan replied to Todd Taylor December 14, 2023 08:03 AM UTC

Thank you Todd ! This is extremely useful. Now menubar component can be used in real world scnenarios.



DB Daniel Bo February 29, 2024 10:08 PM UTC

Maybe the SFMenu didn't use to support navigation but it does now. set the property URI="/......" and it navigates, no need for ton of code. Anyway i wanted to not navigate but render child components consisting of dialogs based on menu clicks. For the sake of context i left all the code in. i used a mix of the index and id solution. 


@*Visible menu component parts*@

<div style="height:inherit">

    <SfMenu @ref="AddMenuObj" Items="menuItems" CssClass="custom-menu" Orientation="Orientation.Horizontal">

        <MenuEvents ItemSelected="SelectedMenuItem" TValue="MenuItem" />

    </SfMenu>

    <SfSwitch @bind-Checked="EditScreenBool" OffLabel="Locked" OnLabel="Edit"></SfSwitch>

</div>


@*Renders dialogs for adding contact informations based on menu selection*@

@if (AddMenuItemId == "1")

{

    <EventDialogRenderFragment Header="Add Kontakt" Visibility="@HideModal">

        <Indhold>

            <NewKontaktDataForm OnSuccessSubmit="@HideModalMethod"></NewKontaktDataForm>

        </Indhold>

    </EventDialogRenderFragment>

}

else if (AddMenuItemId == "11")

{

    <EventDialogRenderFragment Header="Add Email" Visibility="@HideModal">

        <Indhold>

            <NewKontaktEmailDataForm OnSuccessSubmit="@HideModalMethod"></NewKontaktEmailDataForm>

        </Indhold>

    </EventDialogRenderFragment>

}

else if (AddMenuItemId == "12")

{

    <EventDialogRenderFragment Header="Add Telefon" Visibility="@HideModal">

        <Indhold>

            <NewKontaktTelefonDataForm OnSuccessSubmit="@HideModalMethod"></NewKontaktTelefonDataForm>

        </Indhold>

    </EventDialogRenderFragment>

}



@code {

    //Object references

    SfMenu<MenuItem> AddMenuObj;


    public bool EditScreenBool = true; //For rendering purpose in parent component

    private string AddMenuItemId; //Holds the id of the selected menu item

    private bool HideModal { get; set; } = true; //set the initial state of the modal


    //Access Id when clicking a menu item

    private void SelectedMenuItem(MenuEventArgs<MenuItem> args)

    {

        AddMenuItemId = args.Item.Id;

    }


    //Makes the menu items

    private List<MenuItem> menuItems = new List<MenuItem>

     {

        new MenuItem

        {

            Text = "Add Kontakt",

            Id = "1",

            IconCss = "e-icons e-add",

            Items = new List<MenuItem>()

            {

                new MenuItem { Text= "Email", Id = "11" },

                new MenuItem { Text= "Telefon", Id = "12" },

            }

        }

     };


    //set modal visibility on success submit

    private async Task HideModalMethod()

    {

        HideModal = false;

        StateHasChanged();

    }

}




KV Keerthikaran Venkatachalam Syncfusion Team March 4, 2024 01:56 PM UTC

Hi Daniel,


Thanks for sharing the solution.


Regards,

KeerthiKaran K V


Loader.
Up arrow icon