0

经历了各种形式的闪烁和图形故障后,我在网上搜索了可能的解决方案。唯一可以立即使用的解决方案是使用 NativeWinAPI 从下面的帖子中接受的解决方案: 避免在 Windows 窗体中闪烁?

在应用程序的主窗体中插入此代码并保留“this”的句柄实际上消除了我在图形方面遇到的所有问题。

至少在我包含 Web 浏览器(WebView2 控件)之前。该控件与帖子中的代码一起导致控件本身不断地重新绘制自身。这反过来会导致 WebView2 的父级整个用户控件中出现图形问题。其他控件闪烁进出,非常烦人和不愉快。

花了几个小时(实际上是几天)试图找出问题所在并实际上重写了整个项目,问题被定位并在禁用设置窗口样式的功能后立即消失。

我相当确定 WebView2 Control 是唯一有问题的控件,因为我创建了 OnPaint 函数,每次重绘控件时都会写入控制台,并且禁用 webview2 会阻止其他控件被重绘,而启用后,我会在几秒钟内获得 100 次重绘秒。

问题是禁用这些更改会使应用程序看起来更糟,因为它之前修复了所有闪烁和图形故障。

我不明白链接中的代码到底做了什么(对于我目前的知识来说太高级/复杂)。如果有人能帮我弄清楚如何解决这个问题,我将不胜感激。

更新:我为任何有兴趣解决这个问题的人创建了一个小型演示项目。这是放置在谷歌驱动器上的项目的 7zip:

闪烁Demo.7z

WebView2 需要 Microsoft Edge Canary 浏览器才能正常工作: 在此处下载 Edge Canary

主窗体具有控制图形改进和闪烁的布尔标志。只需将其设置为 true/false 即可观察差异。

调试.WriteLine(); - 将 Paint Event 计数器输出到 Visual Studio 的控制台中。

bool FlickerEnabled = false;
public MainForm()
{
    InitializeComponent();
    if (FlickerEnabled)
    {
        InitialiseGraphicalFixes();
    }
}
4

1 回答 1

0

我在我的项目中遇到了同样的问题,我已经设法解决了。在提供的 FickeringDemo.zip 示例中,要停止使用该版本的 WebView2 (1.0.664.37) 闪烁,您应该将所有 .Net 控件中的 DoubleBuffered 属性设置为 true;有关如何执行此操作的示例,请参见下面的代码。

我发现的另一件事是此修复程序停止在 WebView2 1.0.774.44 中工作;在那个版本中,您的其余控件不会轻弹,但 WebView2 会轻弹很多。我没有找到解决方法...

public partial class WebViewControl : UserControl
{
    ...
    public WebViewControl()
    {
        ...
        //the fix to solve flicker if the WS_EX_COMPOSiTED is set on the top window
        SetDoubleBuffered(this, true);
    }
    
    private void SetDoubleBuffered(Control control, bool value)
    {
        try
        {
            control.GetType().GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(control, value, null);
        }
        catch
        {
        }

        foreach (Control child in control.Controls)
        {
            SetDoubleBuffered(child, value);
        }
    }
于 2021-03-17T17:15:45.243 回答