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
相关产品推荐
相关产品推荐

