When there's a WebView2 in the control tree, the contents of the WebView2 are completely blank, though everything else in the image looks fine.
public sealed partial class MainWindow : Window
WebView2 _wv;
public MainWindow()
var b = new Button { Content = new TextBlock { Text = "Do screenshot" } };
b.Click += OnScreenshotClick;
_wv = new WebView2 { Source = new Uri("https://bing.com"), Height=400, Width=400 };
var sp = new StackPanel() { Orientation = Orientation.Vertical };
sp.Children.Add(b);
sp.Children.Add(_wv);
Content = sp;
private async void OnScreenshotClick(object sender, RoutedEventArgs e)
var rootPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
await CaptureAsync(Content, Path.Combine(rootPath, "WindowContent.png"));
await CaptureAsync(_wv, Path.Combine(rootPath, "WebView.png"));
var messageDialog = new MessageDialog($"Screenshots saved to: {rootPath}");
messageDialog.Commands.Add(new UICommand("OK"));
InitializeWithWindow.Initialize(messageDialog, WindowNative.GetWindowHandle(this));
await messageDialog.ShowAsync();
public static async Task CaptureAsync(UIElement element, string destination)
var bmp = new RenderTargetBitmap();
await bmp.RenderAsync(element);
// get the view information first
var width = bmp.PixelWidth;
var height = bmp.PixelHeight;
// then potentially move to a different thread
var pixels = await bmp.GetPixelsAsync();
using FileStream fileStream = new FileStream(destination, FileMode.Create);
var ms = fileStream.AsRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, ms);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)width, (uint)height, 96, 96, pixels.ToArray());
await encoder.FlushAsync();
And then run the app, and click the button in the app.
On my machine it produces two screenshots:
Just the WebView2 (blank rectangle):
The whole app's main window's contents, which has content, except for the blank WebView2 (valid screenshot, except bottom right is blank gray rectangle):
Originally reported in .NET MAUI: dotnet/maui#9718
AB#41360109
@Eilon The WebView2 provides a "CapturePreviewAsync" function which will create a PNG of the web contents. Sounds like the WinUI control would need to incorporate that (or some other mechanism) for RenderAsync. I'm opening a bug for this issue, and we'll ask the WinUI team to take a first look. Thanks!
I do believe that this is an MAUI issue, but since that one has been closed and locked, I will post my workaround here:
I have implemented this for Windows, Android and iOS:
public async Task<byte[]> GetScreenshot()
#if WINDOWS
using var ms = new MemoryStream();
var webview = Handler.PlatformView as WebView2;
await webview.CoreWebView2.CapturePreviewAsync(CoreWebView2CapturePreviewImageFormat.Jpeg, ms.AsRandomAccessStream());
return ms.ToArray();
#elif ANDROID
using var ms = new MemoryStream();
var webview = (Android.Webkit.WebView)Handler.PlatformView!;
var bitmap = Bitmap.CreateBitmap(webview.Width, webview.Height, Bitmap.Config.Argb8888!)!;
var canvas = new Canvas(bitmap);
webview.Draw(canvas);
await bitmap.CompressAsync(Bitmap.CompressFormat.Jpeg, 90, ms);
return ms.ToArray();
#elif IOS
var webview = (WKWebView)Handler.PlatformView!;
UIGraphics.BeginImageContextWithOptions(webview.Bounds.Size, true, 0);
webview.DrawViewHierarchy(webview.Bounds, true);
var jpegData = UIGraphics.GetImageFromCurrentImageContext().AsJPEG();
byte[] dataBytes = new byte[jpegData.Length];
System.Runtime.InteropServices.Marshal.Copy(jpegData.Bytes, dataBytes, 0, Convert.ToInt32(jpegData.Length));
UIGraphics.EndImageContext();
return dataBytes;
#endif
return null;
Here are the necessary usings:
#if IOS
using UIKit;
using WebKit;
#endif
#if ANDROID
using Android.Graphics;
using Path = System.IO.Path;
#endif
#if WINDOWS
using Microsoft.UI.Xaml.Controls;
using Microsoft.Web.WebView2.Core;
#endif
If you would like to use this now you can make your own class that inherits from BlazorWebView and add the above method to it.