Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

MudTabs throws ArgumentOutOfRangeException when loading page with query parameter

$
0
0

I want to set the active panel index based on a query parameter value

Problem Description

When navigating to a Blazor page containing MudTabs with a query parameter specifying the active tab index (e.g., ?tab=1), the application throws an ArgumentOutOfRangeException during the component's first render cycle.

Exception Details

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')   at System.Collections.Generic.List`1.get_Item(Int32 index)   at MudBlazor.MudTabs.OnAfterRenderAsync(Boolean firstRender)

Environment

  • MudBlazor Version: 7.15.0
  • Blazor Hosting Model: Server
  • .NET Version: 9.0

Minimal Reproducible Example

Page Component (.razor)

@page "/example/{Id:long}"@using MudBlazor<MudTabs ActivePanelIndexChanged="@OnActivePanelChanged"         @ref="_tabs"><MudTabPanel Text="Details"><p>Details content</p></MudTabPanel><MudTabPanel Text="Tab 2" Disabled="@(!_enableTab2)"><p>Tab 2 content</p></MudTabPanel><MudTabPanel Text="Tab 3" Disabled="@(!_enableTab3)"><p>Tab 3 content</p></MudTabPanel></MudTabs>

Code Behind (.razor.cs)

public partial class Example : ComponentBase{    [Parameter] public long Id { get; set; }    [Parameter, SupplyParameterFromQuery(Name = "tab")]    public int? TabFromQuery { get; set; }    private MudBlazor.MudTabs? _tabs;    private int? _activePanelIndex;    private int? _pendingIndexFromQuery;    private bool _tabsInitialized;    private bool _enableTab2 = false;    private bool _enableTab3 = false;    protected override Task OnParametersSetAsync()    {        // Store query parameter for later use        if (TabFromQuery is int i && i >= 0)            _pendingIndexFromQuery = i;        return Task.CompletedTask;    }    protected override async Task OnAfterRenderAsync(bool firstRender)    {        await base.OnAfterRenderAsync(firstRender);        // Try to activate the tab from query parameter        if (_tabs?.Panels.Count > 0 && !_tabsInitialized)        {            _tabsInitialized = true;            if (_pendingIndexFromQuery.HasValue)            {                var count = _tabs.Panels.Count;                var index = Math.Min(_pendingIndexFromQuery.Value, count - 1);                _tabs.ActivatePanel(index);                _activePanelIndex = index;                _pendingIndexFromQuery = null;            }            else            {                _activePanelIndex = 0;            }        }    }    private void OnActivePanelChanged(int index)    {        _activePanelIndex = index;    }}

Steps to Reproduce

  1. Create a page with MudTabs and dynamic/disabled panels
  2. Navigate to the page with a query parameter: /example/123?tab=1
  3. Exception is thrown in MudTabs.OnAfterRenderAsync()

Root Cause

The exception occurs during the MudTabs component lifecycle:

  1. OnParametersSetAsync: Query parameter tab=1 is captured
  2. First Render: MudTabs starts rendering, Panels collection is being populated
  3. OnAfterRenderAsync(firstRender: true): MudTabs internally tries to access Panels[ActivePanelIndex]
  4. Problem: At this moment, Panels collection is not yet fully initialized or is empty
  5. Result: ArgumentOutOfRangeException when accessing the index

Expected Behavior

  • MudTabs should handle cases where ActivePanelIndex is set before panels are fully initialized
  • Should gracefully default to index 0 or wait for panels to be ready
  • No exception should occur when navigating with query parameters

Workarounds Attempted

All of these still produce the exception:

❌ Attempt 1: Direct ActivePanelIndex Binding

<MudTabs ActivePanelIndex="@_activePanelIndex" ...>

Result: Same exception during first render

❌ Attempt 2: Using ActivatePanel in OnAfterRenderAsync

if (_tabs?.Panels.Count > 0){    _tabs.ActivatePanel(requestedIndex);}

Result: Exception still occurs before our code executes

❌ Attempt 3: Delaying with StateHasChanged

protected override async Task OnAfterRenderAsync(bool firstRender){    StateHasChanged();    await Task.Delay(100);    _tabs?.ActivatePanel(index);}

Result: Exception occurs before delay

❌ Attempt 4: Setting in OnInitializedAsync

protected override async Task OnInitializedAsync(){    if (_pendingIndexFromQuery.HasValue)        _tabs?.ActivatePanel(_pendingIndexFromQuery.Value);}

Result: _tabs is null, panels don't exist yet


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>