template a blazor RenderFragment to a layout from a page or component

丶灬走出姿态 提交于 2021-01-01 06:32:31

问题


I want to have customizable content in my layout page in blazor. I have tried adding a renderfragment parameter to the layout and adding makeup with the same name in my component but it is not rendered in my layout

eg

layout.razor:

<header>
    @HeaderContent
</header>
@body

@code
{
[Parameter] public RenderFragment HeaderContent { get; set; }

}
component.razor:

<HeaderContent>
<p>my page specific content</p>
</HeaderContnt>

but the headercontent is rendered in the body. can anybody explain how to do this, or why its not possible in a layout. The only way I have found that works is this but it wont refresh the content if I change a bound parameter inside the render fragment


回答1:


  • Flexible Content
  • Clears on Navigation
  • Updates without any wiring up

MainLayout.razor.cs

@inherits LayoutComponentBase

...
    <div class="top-row px-4">
        @headerContent
    </div>

    <div class="content px-4">
        <CascadingValue Value="this">
            @Body
        </CascadingValue>
    </div>
...
@code {
    RenderFragment headerContent => setHeader?.ChildContent;
    SetHeader setHeader;

    public void SetHeader(SetHeader setHeader)
    {
        this.setHeader = setHeader;
        Update();
    }

    public void Update() => StateHasChanged();
}

Setter

public class SetHeader : ComponentBase, IDisposable
{
    [CascadingParameter]
    public MainLayout MainLayout { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void OnInitialized()
    {
        MainLayout.SetHeader(this);
        base.OnInitialized();
    }

    protected override bool ShouldRender()
    {
        var shouldRender = base.ShouldRender();
        if (shouldRender)
        {
            MainLayout.Update();
        }
        return base.ShouldRender();
    }

    public void Dispose()
    {
        MainLayout?.SetHeader(null);
    }
}

Usage

<SetHeader>
    <p>Current count: @currentCount</p>
</SetHeader>




回答2:


The previous answer was pretty close but it didn't work for me. that's how i do fix it:

MainLayout:

<div class="main">
    <div class="top-row px-4">
        @headerContent
        @*<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>*@
    </div>
    <div class="content px-4">
        <CascadingValue Value="this">
            @Body
        </CascadingValue>
    </div>
</div>
@code {
    RenderFragment headerContent => setHeader?.ChildContent;
    SetHeader setHeader;

    public void SetHeader(SetHeader setHeader)
    {
        if (setHeader == null) return;

        this.setHeader = setHeader;
        this.setHeader.OnChange += StateHasChanged;
    }
}

SetHeader:

public class SetHeader : ComponentBase, IDisposable
    {
        [CascadingParameter] public MainLayout MainLayout { get; set; }
        [Parameter] public RenderFragment ChildContent { get; set; }
        
        public event Action OnChange;
        protected override void OnInitialized()
        {
            MainLayout.SetHeader(this);
            Update();
            base.OnInitialized();
        }

        public void Update()
        {
            OnChange?.Invoke();
            StateHasChanged();
        }

        
        public void Dispose()
        {
            MainLayout?.SetHeader(null);
        }

    }

Usage into any razor page:

<SetHeader @ref="@setHeader">
    <p>Current count: @currentCount</p>

    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

</SetHeader>

Into the code of that page:

SetHeader setHeader;

    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
        setHeader.Update();
    }

Now only one problem remains... when you change page you have to put in that page an empty in order to clear it



来源:https://stackoverflow.com/questions/64369596/template-a-blazor-renderfragment-to-a-layout-from-a-page-or-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!