0

My application is built with .NET 8 in Blazor. The configuration in the Program.cs is like this:

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

I want to have a nice sidebar for it. I created a SidebarComponent that generates the sidebar quite nicely. This is the code of the component

@inject NavigationManager _navigationManager
@rendermode InteractiveAuto

<aside id="sidebar" class="sidebar break-point-sm has-bg-image @(_isCollapsed ? "collapsed" : "") @(_isToggled ? "toggled" : "")">
    <a @onclick="BtnCollapseClicked" id="btn-collapse" class="sidebar-collapser"><i class="ri-arrow-left-s-line"></i></a>
    <div class="image-wrapper">
    </div>
    <div class="sidebar-layout">
        <div class="sidebar-header">
            <div class="pro-sidebar-logo">
                <div>P</div>
                <h5>Pro Sidebar</h5>
            </div>
        </div>
        <div class="sidebar-content">
            <nav class="menu open-current-submenu">
                <ul>
                    <li class="menu-header"><span>BLAZOR</span></li>

                    @foreach (var menuItem in standardItems)
                    {
                        <MenuItemComponent MenuItem="@menuItem" MenuItemClickCallback="MenuItemClick" />
                    }
                </ul>
            </nav>
        </div>
    </div>
</aside>

@code {
    private bool _isCollapsed { get; set; } = false;
    private bool _isToggled { get; set; } = false;

    List<MenuItem> standardItems = SidebarData.GetStandardMenuItems();
    List<MenuItem> generalMenuItems = SidebarData.GetGeneralMenuItems();

    public void BtnToggleClicked()
    {
        _isToggled = !_isToggled;
        StateHasChanged();
    }

    public void MouseClickedInOverlay()
    {
        if (_isToggled)
            _isToggled = false;
        generalMenuItems.ForEach(x => x.IsOpened = false);
        StateHasChanged();
    }

   // Omitted
}

Then in the MainLayout, I added

<div class="layout has-sidebar fixed-sidebar fixed-header">
    <SidebarComponent @ref="sideBarComponent"/>

    <div @onclick="@(e => sideBarComponent?.MouseClickedInOverlay())" id="overlay" class="overlay"></div>
    <div class="layout">
    <!-- Omitted -->
    </div>
</div>

When the application starts, I get this error:

System.InvalidCastException: 'Unable to cast object of type 'Microsoft.AspNetCore.Components.Endpoints.SSRRenderModeBoundary' to type 'HypnoPlatform.Client.Pages.Shared.Sidebar.SidebarComponent'.'

enter image description here

How can I call methods from the MainLayout to the SidebarComponent?

1 Answer 1

1

I recall stumbling into this previously. I think the issue is that the line:

<SidebarComponent @ref="sideBarComponent"/>

is, unintuitively, trying to assign an SSRRenderModeBoundary to the variable sideBarComponent, instead of a SidebarComponent. Something to do with the framework wrapping the component with SSRRenderModeBounday when using InteractiveAuto.

I never really got to the bottom of it, but using a shared service to communicate was my solution. Something like:

public class SidebarStateService
{
    public event Action? OnOverlayClicked;

    public void OverlayClicked()
    {
        OnOverlayClicked?.Invoke();
    }
}

Then inject this into both your MainLayout and Sidebar.

Call OverlayClicked from MainLayout and hookup to OnOverlayClicked in your Sidebar.,

Sign up to request clarification or add additional context in comments.

2 Comments

You are right about the origin of the error. I created the SidebarStateService. I have 2 projects: server and client. In the client, I have the sidebar implementation. I added the builder.Services.AddSingleton<SidebarStateService>(); in both Program.cs. When I click on an element in the MainLayout, the Action is not detected from the client side.
I found out how to implement all the parts of the UI. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.