解决C#winForm窗口闪烁问题

716 阅读2分钟

「这是我参与2022首次更文挑战的第40天,活动详情查看:2022首次更文挑战

WinForm程序窗体组件太多,第一次打开的时候加载会出现闪屏的问题。

这样给用户的体验很不好。那么我们应该如何解决这个问题呢?

首先,我们先要找出闪屏的原因。

主要的原因有:使用了很多的组件导致加载缓慢,使用了性能差的组件(PictureBox、Button等)。

我这里大概是有三个解决方案,个人推荐第三种。如果要求不高,前两种也是可以的。

1:在构造方法中设置 ControlStyles 的OptimizedDoubleBuffer 和AllPaintingInWmPaint为True,完全启用双缓冲。

简单说就是当我们在进行画图操作时,系统并不是直接把内容呈现到屏幕上,而是先在内存中保存,然后一次性把结果输出来,如果没用双缓冲的话,你会发现在画图过程中屏幕会闪的很厉害,因为后台一直在刷新,而如果等用户画完之后再输出就不会出现这种情况,具体的做法,其实也就是先创建一个位图对象,然后把内容保存在里面,最后把图呈现出来。

启用双缓冲的首选方法是将该控件的 DoubleBuffered 属性设置为 true,这会产生同样的结果,原因不细说了。

this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

2:设置CreateParams的ExStyle为ExStyle  为 0x02000000 (WS_EX_COMPOSITED)。

设置了这个值之后XP(其他系统好像也可以,没有考证)会把窗体和它的子窗体都开启双缓冲。

protected override CreateParams CreateParams {
      get {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
      }
 }

这个方法重写可能会造成页面执行鼠标移动事件时卡顿

3:这种方法不会加快绘制的过程。当发生绘制时,窗体只是停留在不可见的状态,当绘制完成后就会在屏幕上弹出。

这时窗体的Opacity or TransparencyKey 是不会起作用的,窗体的轮廓是可见的,在绘制区域会出现一个丑陋的黑色矩形框。

要解决这个问题,最好使用计时器来增加不透明度值到99%,以使其在绘制后可见,这样用户就不会看到黑色矩形了。 

public partial class FormDemo : Form
    {
        private Timer Timer = null;
        public FormDemo()
        {
            InitializeComponent();
            Timer = new Timer() { Interval = 100 };
            Timer.Tick += new EventHandler(Timer_Tick);
            base.Opacity = 0;
            Timer.Start();
        }
 
        private void Timer_Tick(object sender, EventArgs e)
        {
            if (this.Opacity >= 1)
            {
                Timer.Stop();
            }
            else
            {
                base.Opacity += 0.2;
            }
        }
    }

以上就是解决winForm加载闪屏的三种方式。

有好的建议,请在下方输入你的评论。

欢迎访问个人博客 guanchao.site

欢迎访问小程序:

在这里插入图片描述