stavroskasidis/BlazorContextMenu

In recursive structure OnClick doesn't work

bsts6124 opened this issue · 5 comments

I'm using .net 5.0 so Use 1.10.1 version

I use recursive structure because treeview.

and child component OnClick is not work...

mainlayout.razor

<div class="page">
    <BlazorContextMenu.ContextMenuTrigger MenuId="EditItem" StopPropagation="true">
        <div class="sidebar">
            @foreach (Model.TreeItemModel tree in db.trees)
            {
                <Component.TreeView Collapse="" Depth="0" Item="tree" />
            }
            <span class="@Collapse()"><i class="oi @CreateItemIcon()" /><input type="text" @bind-Value="@Name" @bind-Value:event="oninput" @onkeydown="@CreateKeyDown" placeholder="@Name item" @ref="Focusing" @onblur="OnBlur" /></span>
        </div>
    </BlazorContextMenu.ContextMenuTrigger>
    @Body
</div>

<BlazorContextMenu.ContextMenu Id="EditItem">
    <BlazorContextMenu.Item OnClick="@(e => OnClickContext(true))">New Folder</BlazorContextMenu.Item>
    <BlazorContextMenu.Item OnClick="@(e => OnClickContext(false))">New File</BlazorContextMenu.Item>
</BlazorContextMenu.ContextMenu>

this item OnClick is work

Component.Treeview.razor

 <div class="@Collapse">
        <BlazorContextMenu.ContextMenuTrigger MenuId="Edit">
            <button class="btn btn-block text-left" style="@Indent()" @onclick="@(()=>Collapsed=!Collapsed)">
                <i class="oi @CollapseIcon()" />
                @Item.Name
            </button> 
            <span class="@CollapseCreate()" style="@pIndent()"><i class="oi @CreateItemIcon()" /><input type="text" @bind-Value="@Name" @bind-Value:event="oninput" placeholder="New Item" @ref="Focusing" @onblur="OnBlur" /></span>
        </BlazorContextMenu.ContextMenuTrigger>
        @foreach (Model.TreeItemModel child in Item.Childs)
        {
            <TreeView Item=child Collapse="@(this.Collapsed ? "collapse":"")" Depth="@Depth" />
        }
</div>

<BlazorContextMenu.ContextMenu Id="Edit">
    <BlazorContextMenu.Item Id="Folder" OnClick="@EditingItem">New Folder</BlazorContextMenu.Item>
    <BlazorContextMenu.Item Id="File" OnClick="@(e => OnClickContext(false))">New File</BlazorContextMenu.Item>
    <BlazorContextMenu.Item Enabled="false">ReName</BlazorContextMenu.Item>
</BlazorContextMenu.ContextMenu>

but this not work

am I must use latest version and .net 6.0? or using wrong way?

Hey devs,

I am trying to do the same thing. I have recursive components in a treeview. I want to have a simple menu shown upon a right click of a child component.

When run, a right click no longer shows the browser's default right click menu. But it does not show the ContextMenu that I have defined in the child. It just does nothing. No errors or crashes.

Unfortunately, I can not my share code but the code provided by bsts6124 is syntactically identical to mine.

Is there a different way to implement it in this scenario? Or does this use case break it?

Thanks

Hey,

I stumbled on the same issue some days ago.

after some debugging, i found that although it looks like the Click does not get through because the menu is not shown, it is actually moved around and should be displayed.

However I found the issue with how it is moved around and that it is clpped outside of the view:

I have a Blazor page displaying a razor component, which includes another razor component. The child component is displayed fine and with the BlazorContextMenu just fine when it is displayed without the hosting component.
If it is displayed as the child, the BlazorMenu just seems to do nothing when right-clicking on the element that should open the Context Menu. All calls until ManualShow(...) are executed.

When viewed with the developer View, the div.blazor-context-menu is located too much to the right and too much to the bottom. Just like the position is no longer absolute but relative to the host component.
Together with an "overflow:hidden;" in the host view, nothing is displayed at all.

If i move left and top via the Browsers devTools to 0px/0px it moves the context menu into view at the top left corner of the child razor component. It sems like calculating the target position is off in this case.

Image: Just after right clicking into the gray area right of the green blocks.
WrongPosition_BlazorContextMenu

Image: After changing the left and top position manually.
WrongPosition_BlazorContextMenu_Manually_set

Found a -dirty- workaround for this:

Once the razor component is loaded, use javascript to change the parent element of the Menu (html element with id == menuid) to the main element. This makes the div use the right anchor for its position.

I guess this has the same cause as the other "wrong position" issues.

Javascript:
function MoveElementToMain(id) { const elementToMove = document.querySelector('#'+id); const newParentElement = document.querySelector('main'); if (elementToMove.parentElement != newParentElement) { newParentElement.appendChild(elementToMove); } }

razor component:
protected override void OnAfterRender(bool firstRender) { base.OnAfterRender(firstRender); JS.InvokeVoidAsync("MoveElementToMain", new object[] { "BusPanelDeviceContextMenu_" + BpdId }); }

You cannot have multiple blazor menus with the same Id. The foreach seams to be creating multiple menus with Id="Edit".
You should move the menu creation outside of the loop

Hey everyone,

I was able to get the context menu to show up in a recursive setting by simply defining the context menu in the parent component. Then, in any child/recursive components, I used the contain context menu triggers to reference that context menu.

In my previous implementation, I had the context menu defined in the recursive component - which was giving me trouble.

It seems that, as @stavroskasidis suggested, it was creating multiple menus with the same ID.

Hope this helps.