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

在Blazor WebAssembly侧边栏添加文本框并同步计数器值的问题

解决方案:Blazor组件间共享状态实现计数器值同步到侧边栏文本框

Blazor组件是独立隔离的,无法直接跨组件访问属性,因此需要通过共享状态服务来实现Counter页面与NavMenu组件的数据同步。以下是具体实现步骤:

1. 创建共享状态服务

新建一个状态服务类,用于存储计数器值并在值变化时通知订阅者:

// Services/CounterStateService.cs
using System;
using System.ComponentModel;

public class CounterStateService : INotifyPropertyChanged
{
    private int _count;

    public int Count
    {
        get => _count;
        set
        {
            if (_count != value)
            {
                _count = value;
                OnPropertyChanged(nameof(Count));
            }
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 注册服务到依赖注入容器

在Program.cs中添加服务注册,让Blazor能够注入该服务:

// Program.cs
builder.Services.AddScoped<CounterStateService>();

3. 修改NavMenu.razor组件

注入状态服务,订阅值变化事件并更新文本框内容:

@inject CounterStateService CounterState
@implements IDisposable

<nav class="flex-column">
    <div class="nav-item px-3">
        <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
            <span class="oi oi-home" aria-hidden="true"></span> Home
        </NavLink>
    </div>
    <div class="nav-item px-3">
        <NavLink class="nav-link" href="counter">
            <span class="oi oi-plus" aria-hidden="true"></span> Counter
        </NavLink>
    </div>
    <div class="nav-item px-3">
        <NavLink class="nav-link" href="fetchdata">
            <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
        </NavLink>
    </div>
    <input type="text" @bind="TextBoxValue" placeholder="Enter text" />
</nav>

@code {
    public string TextBoxValue { get; set; } = "";

    private bool collapseNavMenu = true;
    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    protected override void OnInitialized()
    {
        CounterState.PropertyChanged += OnCounterStateChanged;
        UpdateTextBoxValue();
    }

    private void OnCounterStateChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(CounterState.Count))
        {
            UpdateTextBoxValue();
            StateHasChanged();
        }
    }

    private void UpdateTextBoxValue()
    {
        TextBoxValue = $"当前计数: {CounterState.Count}";
    }

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

    public void Dispose()
    {
        CounterState.PropertyChanged -= OnCounterStateChanged;
    }
}

4. 修改Counter.razor组件

注入状态服务,点击按钮时更新服务中的计数器值:

@page "/counter"
@inject CounterStateService CounterState

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @CounterState.Count</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private void IncrementCount()
    {
        CounterState.Count++;
    }
}

核心逻辑说明

  • 共享状态服务作为数据中间层,存储计数器的唯一真实值
  • Counter组件修改服务中的值时,服务触发PropertyChanged事件
  • NavMenu组件订阅该事件,收到通知后更新文本框内容
  • 实现IDisposable取消事件订阅,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:07:47