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

Blazor中Virtualize组件致二级及以下节点@bind失效问题排查

问题分析与解决方案

核心原因:@bind绑定到组件参数而非可设置属性导致链路断裂

你的问题是用法错误,并非微软Blazor的bug。具体原因:

  • 一级节点的@bind-State="@State"绑定的是根组件的State属性(可读写),点击后能正常触发根组件更新。
  • 二级及以下节点的@bind-State="@State"绑定的是父级NodeComponent的State参数(仅为输入属性,组件内部无法直接修改)。Blazor的@bind语法要求绑定目标是可设置的属性,绑定到参数时,生成的回调无法将更新传递给上层组件,导致绑定链路断裂。

修复方法:让@bind绑定到可触发回调的本地属性

修改NodeComponent,新增一个本地属性封装State参数,通过该属性的setter触发StateChanged回调,让@bind能正常建立双向绑定链路:

修改后的NodeComponent代码

<li @onclick="@(() => SelectNode())">
    <b>@Node.Name</b>
    @if(Node.HasChildren) {
        <ul>
            <Virtualize Items="@Node.Children" Context="node">
                <!-- 改为绑定到LocalState -->
                <NodeComponent @key="node.Id" Node="@node" @bind-State="@LocalState" />
            </Virtualize>
        </ul>
    }
</li>

@code {
    [Parameter]
    public INode Node { get; set; }

    [Parameter]
    public TreeState State { get; set; }

    [Parameter]
    public EventCallback<TreeState> StateChanged { get; set; }

    // 封装本地属性,用于@bind
    private TreeState LocalState
    {
        get => State;
        set => _ = StateChanged.InvokeAsync(value);
    }

    private void SelectNode() {
        var newState = State with { SelectedNode = Node };
        _ = StateChanged.InvokeAsync(newState);
    }
}

原理说明

  • LocalState是可读写的本地属性,getter返回当前的State参数,setter直接调用StateChanged回调向上传递更新。
  • 子组件使用@bind-State="@LocalState"时,Blazor会生成正确的双向绑定逻辑:子组件更新State时触发LocalState的setter,进而调用父组件的StateChanged回调,最终将更新传递到根组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:02:17