You need to enable JavaScript to run this app. Blazor Virtualize实现可搜索多选复选框列表时选中项搜索后不重渲染
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Virtualize实现可搜索多选复选框列表时选中项搜索后不重渲染

问题根因

核心问题出在Virtualize组件的DOM追踪机制上,而非搜索逻辑或复选框双向绑定本身:

  • Blazor 内置的Virtualize组件如果没有显式指定唯一的项追踪键ItemKey,会默认使用「列表项在集合中的索引位置」作为DOM复用的依据。
  • 当执行搜索过滤、替换displayedItems集合内容时,同索引位置对应的列表项对象已经和之前渲染的对象不一致,但Virtualize因为靠索引判断,会错误复用旧位置的DOM元素——也就是观察到的现象:标签文本会跟着新对象的DisplayName更新,但复选框的选中状态还停留在旧DOM元素上,没有和新绑定的对象状态同步。
  • 这个逻辑可以完全复现:比如先选中索引0位置的列表项(此时DOM上的复选框是选中状态),输入搜索词过滤后,原来在索引1的项变成了新集合的索引0位置,Virtualize直接复用这个位置旧的DOM元素,就会出现标签是新项的名字、复选框还保持旧选中状态的异常。
附带的代码隐藏问题

在现有实现里还存在几个容易忽略的隐患:

  • 列表项模型构造函数中存在大小写拼写错误:类中定义的公共选中属性是首字母大写的Selected,但构造函数里写的是this.selected = false(全小写)。由于C#是大小写敏感的语言,这行赋值根本不会作用到公共属性上,虽然bool类型默认值是false碰巧让初始化结果正确,但属于潜在的维护坑。
  • Razor代码块末尾多写了一个无对应开始标签的</ul>闭合标签,会造成DOM结构异常,最好移除。
具体修复方案
  1. 给Virtualize组件补上稳定的唯一追踪键,指定为列表项包裹的原始业务对象(天然唯一,不会因为过滤、排序重复):
<Virtualize Items="@displayedItems" 
            Context="item"
            ItemKey="item => item.Data">
    <ItemContent>
        <label>
            <input type="checkbox" @bind="item.Selected" />
            @item.DisplayName
        </label>
    </ItemContent>
</Virtualize>
  1. 修正列表项模型构造函数中的属性赋值拼写:
public SelectableListItemModel(T data, string displayedPropertyName)
{
    // 修正大小写不匹配的拼写错误
    this.Selected = false;
    this.Data = data;

    if (!string.IsNullOrEmpty(displayedPropertyName))
    {
        this.DisplayName = typeof(T).GetProperty(displayedPropertyName)?.GetValue(data)?.ToString() ?? string.Empty;
    }
    else
    {
        this.DisplayName = data?.ToString() ?? string.Empty;
    }
}
  1. 可选优化:把搜索方法中可读性较差的判断替换为更直观的写法,逻辑完全等价:
protected void Search()
{
    if (!string.IsNullOrWhiteSpace(SearchString))
        displayedItems = items.Where(p => SearchFunc(p.Data, SearchString)).ToList();
    else
        displayedItems = items.ToList();
}

修复后,Virtualize会根据每个项的唯一业务标识来匹配DOM元素,不管集合怎么过滤、顺序怎么变化,只要项存在,就会正确同步复选框的选中状态,不会出现旧DOM状态残留的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.15 07:45:02