C# Windows 窗体滚动闪烁问题

问题描述 投票:0回答:1

这是预览:

视频预览闪烁

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinBlur;
using static WinBlur.UI;

namespace MiTA
{
    public partial class MiTA : Form
    {
        public MiTA()
        {
            InitializeComponent();

            SetStyle(ControlStyles.UserPaint, true);
            UpdateStyles();

            Refresh();

            CheckForIllegalCrossThreadCalls = false;

        }

        protected override void OnScroll(ScrollEventArgs se)
        {
            this.Invalidate();

            base.OnScroll(se);

            base.DoubleBuffered = true;

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            UpdateStyles();

            base.OnScroll(se);

        }

        private const int CS_DROPSHADOW = 0x00020000;

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

                return cp;

                cp.ClassStyle |= CS_DROPSHADOW;
                return cp;
            }
        }

        private void MiTA_Load(object sender, EventArgs e)
        {

        }

        private void MiTA_Shown(object sender, EventArgs e)
        {
            SetBlurStyle(cntrl: this, blurType: BlurType.Mica, designMode: Mode.DarkMode);
        }

        private void label1_MouseEnter(object sender, EventArgs e)
        {
            guna2ImageButton2.ImageSize = new Size(43, 43);
        }

        private void label1_MouseLeave(object sender, EventArgs e)
        {
            guna2ImageButton2.ImageSize = new Size(42, 42);
        }

        private void skglControl1_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)
        {

        }
    }
}

我知道 C# WinForms 使用 GDI+,这非常糟糕,但我确信有一个解决方案。

编辑:添加下面的自定义用户控件的代码

我使用

Guna2PictureBox
而不是
PictureBox
,因为没有任何改变,所以我需要它更加自定义,因为 Guna2PictureBox 具有
BorderRadius
ImageRotate
等属性。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MiTA
{
    public class MiTAPictureBox : Guna.UI2.WinForms.Guna2PictureBox
    {

        public MiTAPictureBox()
        {
            DoubleBuffed = true;
            ResizeRedraw = true;
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer |
                          ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
        }

    }
}

MiTAPanel

using Guna.UI2.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MiTA
{
    public partial class MiTAPanel : Guna2Panel
    {

        public MiTAPanel() : base()
        {
            DoubleBuffed = true;
            ResizeRedraw = true;
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer |
                          ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);
        }
    }

}

我也尝试过所有的控件。

c# graphics flicker
1个回答
0
投票

我决定切换到WPF,根据您的情况,您应该/不应该切换到WPF。一般来说,WPF 为您的应用程序提供了更多的可定制性和图形,这意味着不会有任何闪烁,也可能根本没有延迟,而且您可以说它比 WinForms 更新。它还包含比 Windows 窗体更多的功能。

如果您正在制作一个简单的应用程序,例如计算器,那么最好保留在 Windows 窗体上,这样会花费更少的时间并且更容易制作。

如果您正在制作复杂的应用程序,例如 IDE/代码编辑器/2D 游戏/其他,您绝对应该切换到 WPF。

对我来说切换并不容易,因为我认为这会非常困难,而且我不太喜欢它如何使用XML/XAML。但我可以很坦白地说,我在做出转变后根本就没有回头。作为使用 WinForms 3 年的人,我很自豪能够切换到 WPF。

对于 XML 问题,您始终可以使用 designer,因为 WPF 也有一个。不建议这样做,因为有时它可能会导致问题,但这是您的选择。

this.DoubleBuffer = true

^^ 这是目前最简单的修复,但它不被认为是针对可能滞后/具有大量 UI 的复杂应用程序的修复。

© www.soinside.com 2019 - 2024. All rights reserved.