Yes, but I have no idea about this now.
Sometimes clicking the close button won't refresh, it's really weird
This may be the limitation of blazorise and blazor (I'm not sure)
Add custom
class
andstopPropagation
: The page will flash, but it works.<Tab Name="@tab.TabName" Class="keep-tab-active"> @tab.Title <CloseButton @onclick:stopPropagation="true" Clicked="() => ClosePage(tab)"/> </Tab> .... <TabPanel Name="@route.TabName" Class="keep-panel-active" > ....
Hi,This flash will clear all input boxes and other conditions,It's like refreshing
Clicking the close button will trigger the SelectedTabChanged method of Tabs
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);