Blazor .NET 8 - FluentDialogProvider 面板未显示

问题描述 投票:0回答:1

我正在尝试让 FluentDialogProvider 正常工作,以便它显示一个面板。这是我收到的错误:

warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: <FluentDialogProvider /> needs to be added to the main layout of your application/site. (Parameter 'OnShowAsync')      System.ArgumentNullException: <FluentDialogProvider /> needs to be added to the main layout of your application/site. (Parameter 'OnShowAsync')
         at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowDialogAsync[TData](Type dialogComponent, TData data, DialogParameters parameters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 17
         at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowPanelAsync[TDialog](Object data, DialogParameters parameters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 56
         at S2IX.NodeManager.UI.Web.Shared.Nodes.NodeSnapshots.OpenPanelRightAsync(Guid server) in E:\repos\nodemanager\NodeManager\S2IX.NodeManager.UI.Web\Shared\Nodes\NodeSnapshots.razor:line 108
         at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'BvKsO6dDjcGDj2ubE1pbKa4oPkFQ1ZRukm-frbIFvGI'.
      System.ArgumentNullException: <FluentDialogProvider /> needs to be added to the main layout of your application/site. (Parameter 'OnShowAsync')
         at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowDialogAsync[TData](Type dialogComponent, TData data, DialogParameters parameters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 17
         at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowPanelAsync[TDialog](Object data, DialogParameters parameters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 56
         at S2IX.NodeManager.UI.Web.Shared.Nodes.NodeSnapshots.OpenPanelRightAsync(Guid server) in E:\repos\nodemanager\NodeManager\S2IX.NodeManager.UI.Web\Shared\Nodes\NodeSnapshots.razor:line 108
         at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

我已在 Startup.cs 中注册了组件,并将 DialogueService 添加为作用域。它也在我的 MainLayout.cs 部分中。不太确定这里发生了什么,因为我觉得我已经正确遵循了文档。

程序.cs:

builder.Services.AddScoped<DialogService>();
builder.Services.AddFluentUIComponents();

Mainlayout.cs:

@inherits LayoutComponentBase
@using S2IX.NodeManager.UI.Web.Shared.CommandBars
@using S2IX.NodeManager.Models

<FluentLayout Style="display: flex; height: auto;">
    <FluentHeader style="background-color:#29ABE2; height: 75px;">
        <img src="/Images/s2ixbrand.png" alt="S2IX" />
    </FluentHeader>

    <FluentBodyContent>
        <FluentStack Orientation="Orientation.Horizontal" Style="justify-content: space-between; ">
            @if (collapseMenu)
            {
                <FluentStack Orientation="Orientation.Vertical" Style="width: auto; height: 100vh;">
                    <NavMenu />
                </FluentStack>
            }
            <main style="width:auto;">
                <div class="content">
                    <article id="article">
                        <AppCommandBar />
                        @Body
                    </article>
                </div>
                <FluentToastProvider MaxToastCount="5" Position="ToastPosition.BottomRight" RemoveToastsOnNavigation="true" />
                <FluentDialogProvider />
                <FluentTooltipProvider />
                <FluentMessageBarProvider />
            </main>
        </FluentStack>
    </FluentBodyContent>

</FluentLayout>



@code {
        bool collapseMenu = true;

        void ToggleMenu()
        {
            collapseMenu = !collapseMenu;
            StateHasChanged();
        }
}

NodeSnapshots.cs:

@inject ApplicationStateService stateService
@inject NavigationManager navMan
@inject IDialogService DialogService

@rendermode RenderMode.InteractiveServer


@if (!nodesFound)
{
    @if (!showDialog)
    {
        <FluentProgressRing>Loading Nodes...</FluentProgressRing>
    }
    else
    {
        <p>No Nodes found</p>
    }
}
else
{
    <FluentDataGrid Items="@FilteredItems" ResizableColumns="false" Pagination="@pagination" Style="overflow:auto;">
        <PropertyColumn Title="Name" Property="@(n => n.Name)" Sortable="true">
            <ColumnOptions>
                <div class="search-box">
                    <FluentSearch type="search" Autofocus="true" @bind-Value=nodeFilter @oninput="HandleNameFilter" @bind-Value:after="HandleClear" Placeholder="Node name..." />
                </div>
            </ColumnOptions>
        </PropertyColumn>
        <PropertyColumn Title="Description" Property="@(n => n.Description)" Sortable="false" />
        <TemplateColumn Title="Servers" Align="Align.Start">
            <p @onclick="@(() => OpenPanelRightAsync(@context.Servers[0]))">@context.Servers.Count</p>
        </TemplateColumn>
        <TemplateColumn Title="" Align="Align.Start">
            <FluentIcon Value="@(new Icons.Regular.Size24.Edit())" OnClick="@(() => Edit(@context))" />
        </TemplateColumn>
    </FluentDataGrid>

}



@code {
    // UI
    private PaginationState pagination = new PaginationState { ItemsPerPage = 20 };
    private bool showDialog = false;
    private IDialogReference? _dialog;

    // Nodes
    IQueryable<S2IXNodeDto>? nodesGrid;
    bool nodesFound = false;

    // Filter
    string nodeFilter = string.Empty;
    IQueryable<S2IXNodeDto>? FilteredItems => nodesGrid?.Where(n => n.Name.Contains(nodeFilter, StringComparison.CurrentCultureIgnoreCase));

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            stateService.SetAddNode(false);
            stateService.SetEditNode(false);
            stateService.SetAddSelectedNode(null);

            using (HttpClient httpClient = new HttpClient())
            {
                NodeClient nodeClient = new NodeClient(httpClient);
                var result = await nodeClient.GetAllNodes();

                nodesGrid = result.OrderBy(n => n.Name).AsQueryable();
                nodesFound = nodesGrid.Any();

                if (!nodesFound)
                {
                    showDialog = true;
                }
            }
        }
        StateHasChanged();
    }

    private void Edit(S2IXNodeDto nodeDto)
    {
        stateService.SetAddSelectedNode(nodeDto);
        stateService.SetEditNodeNetwork(true);
        navMan.Refresh(true);
    }
    private void HandleClear()
    {
        if (string.IsNullOrEmpty(nodeFilter))
        {
            nodeFilter = string.Empty;
        }
    }
    private void HandleNameFilter(ChangeEventArgs args)
    {
        if (args.Value is string value)
        {
            nodeFilter = value;
        }
    }
    private async Task OpenPanelRightAsync(Guid server)
    {
        using (HttpClient httpClient = new HttpClient())
        {
            ServerClient serverClient = new ServerClient(httpClient);
            ServerDto result = await serverClient.GetServer(server.ToString());

            _dialog = await DialogService.ShowPanelAsync<SimpleServerPanel>(result, new DialogParameters<ServerDto>()
            {
                Content = result,
                Title = $"Hello {result.Name}",
                Alignment = HorizontalAlignment.Right,
                PrimaryAction = "Close"
            });
            DialogResult panel = await _dialog.Result;
            HandlePanel(panel);
        }
    }

    private static void HandlePanel(DialogResult result)
    {
        if (result.Cancelled)
        {
            return;
        }

        if (result.Data is not null)
        {
            var server = result.Data as ServerDto;
            return;
        }
    }
}

SimpleServerPanel.razor:

@implements IDialogContentComponent<ServerDto>

<FluentDialogBody>
    <h3>Servers</h3>

    <FluentTextField @bind-Value="@Content.Name">This is a test:</FluentTextField>

</FluentDialogBody>



@code 
{
    [Parameter]
    public ServerDto Content { get; set; } = default!;
}

任何帮助将不胜感激!

c# blazor .net-8.0 fluent-ui
1个回答
0
投票

答案是,在我的 MainLayout 中,我必须将 @rendermode="RenderMode.InteractiveServer" 添加到 FluentDialogProvider 例如:

<FluentDialogProvider @rendermode="RenderMode.InteractiveServer"/>

很遗憾文档中没有提到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.