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

VB WinForm ListBox垂直滚动黑屏闪烁重绘异常问题求助

解决方案

1. 开启ListBox双缓冲(优先尝试,可解决绝大多数滚动闪烁/黑屏问题)

WinForm自带的ListBox默认未启用双缓冲,滚动时极易出现闪烁、背景变黑的问题,你可以通过两种方式开启双缓冲:

  • 方式一:自定义继承ListBox的控件,编译后替换原有ListBox即可
Public Class DoubleBufferedListBox
    Inherits ListBox
    Public Sub New()
        Me.DoubleBuffered = True
        ' 额外开启重绘优化参数
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True)
        Me.UpdateStyles()
    End Sub
End Class
  • 方式二:通过反射直接给现有ListBox开启双缓冲,代码放在Form_Load事件中即可
Dim pi As System.Reflection.PropertyInfo = GetType(ListBox).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.NonPublic)
pi.SetValue(ListBox1, True, Nothing)

2. 优化Timer事件逻辑

你代码中开启了间隔200ms的Timer1,如果Timer的Tick事件中存在频繁修改UI、更新ListBox项的操作,会和控件自身的滚动重绘产生冲突,导致异常:

  • 仅当ListBox内容确实发生变更时才执行更新操作,不要每次Tick都清空并重载所有项
  • 更新ListBox前调用ListBox1.BeginUpdate(),更新完成后调用ListBox1.EndUpdate(),减少重复重绘次数

3. OwnerDrawFixed模式显示为空的解决方法

开启自绘模式后必须手动实现DrawItem事件才能正常显示内容,示例代码如下:

Private Sub ListBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ListBox1.DrawItem
    e.DrawBackground()
    If e.Index >= 0 AndAlso e.Index < ListBox1.Items.Count Then
        e.Graphics.DrawString(ListBox1.Items(e.Index).ToString(), e.Font, Brushes.Black, e.Bounds.X, e.Bounds.Y)
    End If
    e.DrawFocusRectangle()
End Sub

如果无需自定义项样式,不建议开启OwnerDraw模式,使用双缓冲方案即可。

4. 额外优化建议

  • 若ListBox加载项数量超过1000条,可开启虚拟化:将ListBox1.VirtualMode设为True,配合VirtualListSize和RetrieveVirtualItem事件使用,大幅降低大数据量下的重绘压力
  • 检查Form层面是否开启了透明效果、复杂背景图绘制等逻辑,这类逻辑也会加重控件重绘负担导致异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 17:45:01