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

如何解决ListView更新时UI频繁闪烁的问题

解决ListView更新时UI频繁闪烁的问题

我太懂这种ListView疯狂闪烁的糟心体验了!本质上是因为你每次更新都在频繁触发UI重绘,加上默认的控件绘制机制没做批量优化,才导致了这种晃眼的效果。结合你给出的代码片段,给你几个立竿见影的解决办法:

1. 给ListView启用双缓冲

双缓冲的核心逻辑是让控件先在内存里完成所有绘制操作,再一次性把结果渲染到屏幕上,避免逐行绘制带来的闪烁。不过系统自带的ListView的DoubleBuffered属性是受保护的,你可以通过两种方式开启:

  • 如果你是自己写的自定义ListView控件,直接在构造函数里加:
this.DoubleBuffered = true;
  • 如果用的是工具箱拖进来的默认ListView,用反射来设置(建议在窗体初始化的时候执行一次就行):
typeof(ListView).InvokeMember(
    "DoubleBuffered",
    BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
    null,
    listView3,
    new object[] { true }
);

2. 批量更新时暂停控件重绘

你现在的逻辑是先清空ListView,再逐个添加驱动器项——每一次清空、每添加一个项都会触发一次重绘,累积起来就闪得厉害。用BeginUpdate()和EndUpdate()把你的更新逻辑包裹起来,就能让控件在这段时间内不重绘,直到所有操作完成后一次性渲染:

修改你的代码如下:

if (text.StartsWith("fdrivel§")) //客户端发送驱动器列表
{
    String data = text.Split('§')[1]; //获取驱动器列表
    
    listView3.BeginUpdate(); // 暂停重绘
    try
    {
        LvClear(listView3); //清空驱动器ListView
        foreach (String drive in data.Split('\n')) //遍历驱动器
        {
            // 记得跳过空字符串,避免添加无效项
            if (!string.IsNullOrWhiteSpace(drive))
            {
                listView3.Items.Add(drive);
            }
        }
    }
    finally
    {
        listView3.EndUpdate(); // 恢复重绘,一次性渲染所有更改
    }
}

用try...finally包裹是为了确保哪怕中间出现异常,控件也能恢复重绘状态,不会一直卡住。

3. 优化你的LvClear方法

如果你的LvClear是通过循环逐个删除ListView项实现的,那也会触发多次重绘。建议直接替换成listView3.Items.Clear()——这个方法内部已经做了批量优化,比手动循环删除高效得多,还能减少闪烁。

总结

优先用BeginUpdate()/EndUpdate()包裹批量操作,再加上双缓冲设置,基本上就能解决你当前遇到的闪烁问题。如果之后要处理更大数据量的文件列表,还可以考虑用ListView的虚拟模式(VirtualMode),不过对你现在的场景来说,前面两个方法已经足够啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:43:05