WinForm自定义Panel控件按Tab切换时闪烁无法消除如何解决
解决方法
- 优先尝试最简单的方案:如果你这些动态插入的
Panel不需要通过Tab键获得焦点,直接在创建控件时将TabStop属性设为False,90%的Tab遍历闪烁问题都可以通过这个设置直接解决
Dim ModSe As Bitmap = Nothing ModSe = My.Resources.example Dim pbdoors As New Panel With { .Width = 100, .Height = 200, .Top = 10, .Left = 10, .BorderStyle = BorderStyle.FixedSingle, .BackgroundImage = ModSe, .BackgroundImageLayout = ImageLayout.Stretch, .ContextMenuStrip = CntxtMnuStrpUnit, .Name = ("Test"), .TabStop = False ' 新增这行即可 }
- 如果你确实需要
Panel支持Tab聚焦,修改你的FlickerPanel实现,原代码的ControlStyles.Opaque设置错误会导致背景绘制冲突,修正后的代码如下:
Public Class FlickerPanel Inherits System.Windows.Forms.Panel Public Sub New() MyBase.New() ' 关闭Opaque,开启UserPaint才能让自定义双缓冲逻辑生效 Me.SetStyle(ControlStyles.UserPaint, True) Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) Me.SetStyle(ControlStyles.ResizeRedraw, True) Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True) Me.UpdateStyles() End Sub ' 重写背景绘制逻辑,避免系统默认擦除背景触发闪烁 Protected Overrides Sub OnPaintBackground(pevent As PaintEventArgs) If Me.BackgroundImage IsNot Nothing Then pevent.Graphics.DrawImage(Me.BackgroundImage, Me.ClientRectangle) Else MyBase.OnPaintBackground(pevent) End If End Sub End Class
- 动态添加多个子控件时,先给父容器调用
SuspendLayout暂停布局重绘,所有控件添加完成后再调用ResumeLayout,避免单次添加控件触发多次全局重绘:
' 父容器假设名为ParentPanel ParentPanel.SuspendLayout() ' 循环添加所有子FlickerPanel的逻辑写在此处 ParentPanel.ResumeLayout()
- 最后在Form的构造函数里添加以下代码,开启窗体级别的绘制优化:
Public Sub New() InitializeComponent() Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) Me.UpdateStyles() End Sub
内容的提问来源于stack exchange,提问作者LARC
相关产品推荐
相关产品推荐

