Hi,
Here is the code,
But there is a serious problem when deleting the tab, which may be related toblazor.zone
. There is nothing I can do. so, I don't recommend you to useblazor.zone
<BootstrapBlazor.Components.Tab @ref="_tabComponent" class="mt-3" ShowClose="true" OnClickTabItemAsync="OnSelectedTabChanged" OnCloseTabItemAsync="ClosePage"> @foreach (var tab in RouteDataList) { <BootstrapBlazor.Components.TabItem Text="@tab.Title"> <ContentTabToolbar RouteData="tab"></ContentTabToolbar> @tab.Body </BootstrapBlazor.Components.TabItem> } </BootstrapBlazor.Components.Tab> @code { private BootstrapBlazor.Components.Tab _tabComponent; [Inject] NavigationManager NavigationManager { get; set; } [Inject] PageHeaderService PageHeaderService { get; set; } [Inject] IMenuManager MenuManager { get; set; } [CascadingParameter(Name = "RouteData")] RouteData? RouteData { get; set; } List<ContentTabRouteData> RouteDataList { get; set; } = new(); [Parameter] public RenderFragment Body { get; set; } string? CurrentUrl { get; set; } ApplicationMenu? ApplicationMenu { get; set; } protected override async Task OnInitializedAsync() { ApplicationMenu = await MenuManager.GetMainMenuAsync(); PageHeaderService.PageHeaderDataChanged += OnPageHeaderDataChanged; NavigationManager.LocationChanged += OnLocationChanged; } protected override void OnAfterRender(bool firstRender) { if (firstRender) { OnLocationChanged(this, new LocationChangedEventArgs(NavigationManager.Uri, false)); } base.OnAfterRender(firstRender); } private async void OnPageHeaderDataChanged(object? sender, PageHeaderData? e) { if (e == null) { return; } var route = RouteDataList.FirstOrDefault(x => x.PageType == e.Type); route?.SetPageLayout(e.Title, e.BreadcrumbItems, e.PageToolbarItems); await InvokeAsync(StateHasChanged); } private async Task OnSelectedTabChanged(BootstrapBlazor.Components.TabItem tabItem) { var route = RouteDataList.FirstOrDefault(x => x.Title == tabItem.Text); if (route != null) { CurrentUrl = route.Url; var data = PageHeaderService.GetPageHeaderData(route.PageType); if (data != null) { route.SetPageLayout(data.Title, data.BreadcrumbItems, data.PageToolbarItems); } _tabComponent.ActiveTab(tabItem); NavigationManager.NavigateTo(route.Url); } await InvokeAsync(StateHasChanged); } private RenderFragment GenerateBody(ContentTabRouteData routeData) { return builder => { builder.OpenComponent(0, routeData.PageType); foreach (var routeValue in routeData.RouteValues) { builder.AddAttribute(1, routeValue.Key, routeValue.Value); } builder.CloseComponent(); }; } private async Task<bool> ClosePage(TabItem tabItem) { var routeData = GetRouteData(tabItem); if (routeData == null) { return true; } RouteDataList.Remove(routeData); await _tabComponent.RemoveTab(tabItem); var activeTab = _tabComponent.GetActiveTab(); if (activeTab != null) { await OnSelectedTabChanged(activeTab); } return false; } private ContentTabRouteData? GetRouteData(TabItem? tabItem) { return tabItem == null ? null : RouteDataList.FirstOrDefault(x => x.Title == tabItem.Text); } private void OnLocationChanged(object? sender, LocationChangedEventArgs e) { if (RouteData == null || CurrentUrl == e.Location) { return; } var contentTabRouteData = new ContentTabRouteData { PageType = RouteData.PageType, RouteValues = new Dictionary<string, object>(RouteData.RouteValues), TabName = RouteData.PageType.Name.ToLower(), Url = e.Location, Title = TryGetTitle(ApplicationMenu.Items, e.Location) }; contentTabRouteData.Body = GenerateBody(contentTabRouteData); RouteDataList.AddIfNotContains(x => x.PageType == RouteData.PageType, () => contentTabRouteData); StateHasChanged(); OnSelectedTabChanged(_tabComponent.Items.First(x => x.Text == contentTabRouteData.Title)); } protected override void Dispose(bool disposing) { PageHeaderService.PageHeaderDataChanged -= OnPageHeaderDataChanged; NavigationManager.LocationChanged -= OnLocationChanged; base.Dispose(disposing); } private string? TryGetTitle(ApplicationMenuItemList items, string url) { foreach (var item in items) { if (item.Items.Any()) { var result = TryGetTitle(item.Items, url); if (result != null) { return result; } continue; } if (item.Url.IsNullOrWhiteSpace()) { continue; } if (url.EndsWith(item.Url!.Replace("~/", ""))) { return item.DisplayName; } } // you can custom here return null; } }
Hi.What's the problem with closing it?
Hi,
I got it.
Please make the repository private.
Because it includes your license code, you don't want to leak it.
ok
Hi,
I don't know much about blalzor.zone
Can you share a test project? thanks. shiwei.liang@volosoft.com
https://github.com/He-Wu/BootstrapDemo1 Please help me take a look
The content tab component try get
Title
from PageHeader and Menu item.But the detail page didn't have PageHeader and menuItem.
You can also implement your own logic to get the page title from other places. The https://gist.github.com/realLiangshiwei/a71887cb41b679739599ce52b30ec151#file-contenttabs-razor-L210
When too many tabs are selected, the line will break. I want to change it to the above form and replace it with a UI framework (https://www.blazor.zone/tab), but the page cannot jump after clicking after menu bar
Hi,
Please add
Title
to pageHeader compoent:<PageHeader Title="PageName..." BreadcrumbItems="breadcrumbItems" Toolbar="toolbar"></PageHeader>
Another problem is that when I click the button to enter the details page, the url will have a corresponding id. At this time, the top tab is blank NavigationManager.NavigateTo("/Finances/ExchangeRates/HistoricalExchangeRateRecords/" + Id);
Have you applied the latest code? you can check it.
yes,is the latest
Have you applied the latest code? you can check it.
this is my code
@* ************************* PAGE HEADER ************************* *@
<Volo.Abp.AspNetCore.Components.Web.Theming.Layout.PageHeader BreadcrumbItems="breadcrumbItems" Toolbar="toolbar"></Volo.Abp.AspNetCore.Components.Web.Theming.Layout.PageHeader>
@* ************************* DATA GRID ************************* *@
<LDMutiSelect TValue="Guid" GetData="GetData"></LDMutiSelect>`
`private List<Volo.Abp.BlazoriseUI.BreadcrumbItem> breadcrumbItems = new List<Volo.Abp.BlazoriseUI.BreadcrumbItem>() { new Volo.Abp.BlazoriseUI.BreadcrumbItem("demo1", "/aaa", "aaa") };
private PageToolbar toolbar = new();
protected override void OnInitialized()
{
toolbar.AddButton("Test", () => Task.CompletedTask);
//父组件TableOption初始化之后再初始化子组件
base.OnInitialized();
}
I know that BreadcrumbItems have been deleted, but the toolbar button is no longer on my page. The tenant page is but the newly created page is not.
Updated
Hi I just discovered a fatal bug. The Toolbar and breadcrumbItems in the PageHeader in the code generated by abp suite will not be displayed, and the tab content will be blank. <Volo.Abp.AspNetCore.Components.Web.Theming.Layout.PageHeader BreadcrumbItems="breadcrumbItems" Toolbar="toolbar"></Volo.Abp.AspNetCore.Components.Web.Theming.Layout.PageHeader>
Hi,
I updated the code: https://gist.github.com/realLiangshiwei/a71887cb41b679739599ce52b30ec151
Now it basically works, maybe there may be some minor problems, but not a big problem.
This is a big work, and I can't make it perfect in a short time : )You can change it according to your needs.
Hello, there is a big problem here, that is, after I clicked on the menu page created using abp suite, the tab above was blank and wrong, and the create button of the tenant page also appeared in the demo4 page, and the top The tab has no translation