You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI Blazor中ActiveContext重渲染后值无法保留的问题

问题解决:Blazor导航项选中状态在重渲染后丢失的处理方案

你的问题核心在于ActiveContext是组件内部的普通私有字段,当组件因路由切换、父组件重渲染等原因销毁重建时,该字段会被重新初始化,导致选中状态丢失。以下是几种实用的解决办法:


方案一:利用NavLink原生激活功能(最推荐)

Blazor的NavLink组件本身支持根据当前路由自动添加激活类,完全不需要手动维护状态:

  1. 直接修改NavLink的ActiveClass参数,指定你需要的选中类名(比如selected):
<NavLink class="bottom-bar-nav-link" 
         ActiveClass="selected" 
         href="" 
         Match="NavLinkMatch.All">
    <div class="icon-wrapper">
        <img src="img/main-icon.svg"/>
    </div>
    <span>Головна</span>
</NavLink>
  1. 其他导航项同理修改,移除所有手动维护ActiveContext的代码(包括SwitchNavBarActiveClass方法和onclick事件)。

这种方式的优势:

  • 自动适配路由变化(包括用户直接输入URL刷新页面的场景)
  • 无需手动维护状态,避免重渲染导致的状态丢失
  • 符合Blazor组件的设计规范

方案二:持久化组件状态(.NET 7+)

如果必须手动维护状态,可以使用PersistentComponentState保存状态,组件销毁重建时自动恢复:

@inject PersistentComponentState State
@implements IDisposable

<footer class="bottom-bar-wrapper">
    <!-- 原导航项代码不变,class绑定仍使用ActiveContext -->
</footer>

@code {
    private string[] ActiveContext;
    private readonly PersistingComponentStateSubscription _subscription;

    protected override void OnInitialized()
    {
        // 尝试从持久化状态恢复,没有则初始化
        if (!State.TryGetFromJson<string[]>("NavActiveState", out var savedState))
        {
            ActiveContext = new[] { "selected", "", "", "", "" };
        }
        else
        {
            ActiveContext = savedState;
        }

        // 订阅组件持久化事件,销毁前保存状态
        _subscription = State.RegisterOnPersisting(() =>
        {
            State.PersistAsJson("NavActiveState", ActiveContext);
            return Task.CompletedTask;
        });
    }

    public void Dispose()
    {
        _subscription.Dispose();
    }

    // 原SwitchNavBarActiveClass方法不变
    private void SwitchNavBarActiveClass(int itemIndex)
    {
        for (int i = 0; i < ActiveContext.Length; i++)
        {
            ActiveContext[i] = i == itemIndex ? "selected" : string.Empty;
        }
    }
}

方案三:全局状态容器

将导航状态放在全局单例服务中,组件无论如何重建都能获取最新状态:

  1. 创建全局状态服务:
public class NavStateService
{
    public int ActiveIndex { get; private set; } = 0;

    public void SetActiveIndex(int index)
    {
        ActiveIndex = index;
        OnActiveIndexChanged?.Invoke();
    }

    public event Action OnActiveIndexChanged;
}
  1. 在Program.cs注册为单例:
builder.Services.AddSingleton<NavStateService>();
  1. 在导航组件中使用:
@inject NavStateService NavState
@implements IDisposable

<footer class="bottom-bar-wrapper">
    <div class="container-fluid">
        <nav class="bottom-bar flex-row">
            <div class="nav-item px-1"></div>
            <div class="nav-item px-2">
                <NavLink class=@($"bottom-bar-nav-link {NavState.ActiveIndex == 0 ? "selected" : ""}") 
                         @onclick="() => NavState.SetActiveIndex(0)" 
                         href="" 
                         Match="NavLinkMatch.All">
                    <div class="icon-wrapper">
                        <img src="img/main-icon.svg"/>
                    </div>
                    <span>Головна</span>
                </NavLink>
            </div>
            <!-- 其他导航项按此格式修改 -->
        </nav>
    </div>
</footer>

@code {
    protected override void OnInitialized()
    {
        NavState.OnActiveIndexChanged += StateHasChanged;
    }

    public void Dispose()
    {
        NavState.OnActiveIndexChanged -= StateHasChanged;
    }
}

内容的提问来源于stack exchange,提问作者Kolya Ferents

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:22:35