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

代码选中ListViewItem时偶发NullReferenceException问题排查求助

解决WinForms ListView设置Selected时的偶发NullReferenceException

这个问题我在WinForms开发中踩过类似的坑,结合你的代码和堆栈信息,咱们来拆解分析原因和解决办法:

核心原因分析

从堆栈看异常出在ListViewItem.set_Selected方法里,大概率不是你的lvi为空(毕竟刚实例化还添加到了集合),而是ListView内部控件状态未完全初始化,或者跨线程操作控件导致的:

  • 刚把ListViewItem添加到集合就立刻设置Selected,ListView可能还没完成该项的内部绑定,此时操作Selected会触发内部空引用
  • 如果这段代码在非UI线程执行,WinForms控件的线程不安全特性会引发各种诡异的偶发异常,包括这种空引用

解决方案

1. 先批量添加所有项,再统一设置选中

把选中逻辑移到所有项添加完成之后,避免在ListView内部状态不稳定时操作Selected:

this.listView.Items.Clear();
// 先批量添加所有项
foreach(var obj in objectList) {
    // 防御性检查:避免obj为空导致后续报错
    if (obj == null) continue;
    var lvi = new ListViewItem(new[] {obj.Column1 ?? "", obj.Column2 ?? ""}) { Tag = obj };
    this.listView.Items.Add(lvi);
}

// 所有项添加完成后,再查找并设置选中
var targetItem = this.listView.Items.Cast<ListViewItem>()
    .FirstOrDefault(lvi => {
        var itemObj = lvi.Tag as YourObjectType; // 替换成你的实际对象类型
        return itemObj != null && string.Equals(itemObj.Column1, selectedData, StringComparison.Ordinal);
    });

if (targetItem != null) {
    targetItem.Selected = true;
    // 可选:让选中项自动滚动到可视区域
    this.listView.EnsureVisible(targetItem.Index);
}

2. 确保代码在UI线程执行

WinForms控件只能在创建它的UI线程操作,加个线程检查避免跨线程问题:

if (this.listView.InvokeRequired) {
    this.listView.Invoke(new Action(() => {
        // 把上面的填充和选中逻辑放在这里
    }));
    return;
}

// 下面执行正常的填充逻辑

3. 增加null安全的字符串比较

用string.Equals替代直接==,可以安全处理obj.Column1或selectedData为空的情况,避免额外的空引用隐患。

额外提示

如果你的ListView在窗体还未显示时就执行这段代码,可能控件的Handle还未创建,可以提前调用this.listView.CreateControl()强制创建控件句柄,确保内部状态初始化完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:19:46