在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
相关产品推荐
相关产品推荐

