iluzek
iluzek

Reputation: 35

C# Excessive Repainting of WebView2 Control after Applying NativeWinAPI Styles

Having experiences various forms of flickering and graphical glitches, I searched online for possible solution. The only thing that worked straight away was accepted solution using NativeWinAPI from post just below: Avoid Flickering in Windows Forms?

Inserting this code in the main form of the application and keeping handle for 'this' practically eliminated every issue I had with graphics.

At least until I included a web browser (WebView2 Control). This control along side with the code from the post causes the control itself to constantly repaint itself. This in turn causes graphical issues within entire User Control that is parent to the WebView2. Other controls flicker in and out, which is super annoying and unpleasant.

Having spent hours(days really) trying to figure out what is wrong and practically rewriting entire project, the issue was located and it disappears straight after disabling function that sets the window style.

I am fairly certain that WebView2 Control is the only control having issues as I created OnPaint functions that write to console every time that the control was repainted, and disabling webview2 stops other controls from being repainted, while when enabled I get 100's of repaints within few seconds.

The problem is that disabling those changes makes the application look even worse with all the flickering and graphical glitches that it was fixing before.

I do not understand what the code from the link exactly does (too advanced/complex for my current knowledge). If anyone could help me figure out how to solve the issue I would really appreciate it.

Update: I created a small demo project for anyone interested in addressing this. It is a 7zip of the project placed on google drive:

FlickeringDemo.7z

Microsoft Edge Canary Browser is required for WebView2 to work correctly: Download Edge Canary Here

Main form has bool flag that control graphical improvements and flickering. Simply set it to true/false to observe the difference.

Debug.WriteLine(); - will output Paint Event counter into console in Visual Studio.

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

Upvotes: 1

Views: 1359

Answers (1)

Antonio Cunha
Antonio Cunha

Reputation: 21

I was having the same problem in my project and I've managed to solve it. In the provided FickeringDemo.zip sample, to stop flickering with that version of WebView2 (1.0.664.37) you should set to true the DoubleBuffered property in all of your .Net Controls; see code below for an example on how to do it.

Another thing that I've found is that this fix stops to working in WebView2 1.0.774.44; in that version the rest of your controls will not flick, but the WebView2 will flick a lot. I didn't find a way to solve it...

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);
        }
    }

Upvotes: 2

Related Questions