WebView control for Windows Forms and WPF

The WebView control shows web content in your Windows Forms or WPF desktop application.

WebView example

This control uses the Microsoft Edge rendering engine to embed a view that renders richly formatted HTML content from a remote web server, dynamically generated code, or content files.

About WebView controls

The Windows Forms version of this control is located in the Microsoft.Toolkit.Forms.UI.Controls namespace in the Microsoft.Toolkit.Forms.UI.Controls.WebView NuGet package. The WPF version is located in the Microsoft.Toolkit.Wpf.UI.Controls namespace in the Microsoft.Toolkit.Wpf.UI.Controls.WebView NuGet package. You can find additional related types (such as event args classes) in the Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT namespace.

These controls wrap an instance of the WebViewControl class, and they provide a subset of members from that class. The WebViewControl is similar to the WebView class, but it is designed to run out of process in a desktop application (such as a WPF or Windows Forms application) and it supports a smaller set of members.

Unless specified otherwise in this article, the documentation for the WebViewControl class applies to the WPF and Windows Forms WebView controls. This article links to reference pages for the UWP WebViewControl class for more information about most members.

Prerequisites

✔️ Visual Studio 2017.

✔️ Windows 10 Insider Preview Build 17110 or a later release.

✔️ .NET Framework 4.6.2 or a later release.

✔️ Configure your application for high DPI support. To learn how, see this section of the guide.

Feature limitations

When compared to the UWP WebView control, the current release of the WPF and Windows Forms WebView control has some limitations. For the complete list of these limitations, see Known Issues of the WebView control for Windows Forms and WPF applications.

Add the WebView control to the Visual Studio Toolbox for Windows Forms applications

For Visual Studio 15.8 and later:

  1. Install the Microsoft.Toolkit.Forms.UI.Controls.WebView NuGet package.

  2. Open the Toolbox in Visual Studio. The WebView control appears in the General section of the Toolbox and you can drag it directly the designer.

For earlier versions of Visual Studio:

  1. Install the Microsoft.Toolkit.Forms.UI.Controls.WebView NuGet package.

  2. Open the Toolbox in Visual Studio, right-click anywhere in the toolbox, and select the Choose Items option.

  3. In the .NET Framework Components tab of the Choose Toolbox Items dialog box, click Browse to locate the Microsoft.Toolkit.Forms.UI.Controls.WebView.dll in your NuGet package folder.

  4. Add Microsoft.Toolkit.Forms.UI.Controls.WebView.dll to the list of Toolbox controls, and then close the Choose Toolbox Items dialog box.

    The WebView control appears in the General section of the Toolbox.

    In Solution Explorer, the Microsoft.Toolkit.Forms.UI.Controls.WebView assembly appears in the References list.

Add the WebView control to the Visual Studio Toolbox for WPF applications

  1. Install the Microsoft.Toolkit.Wpf.UI.Controls.WebView NuGet package.

  2. Open the Toolbox in Visual Studio or Blend. The WebView control appears in the Windows Community Toolkit section of the Toolbox and you can drag it directly the designer. You can also create an instance of the WebView control in code, but we recommend that you do not add WebView controls to popup windows because support for that scenario will soon be disabled for security reasons.

Enable the WebView control to appear properly on high DPI displays

If users open your application on displays that have a high Dots Per Inch (DPI) displays, your WebView won't appear at the proper scale unless you configure your application first.

Configure a Windows Forms application

For guidance, see Configuring your Windows Forms app for high DPI support.

Configure a WPF application

Add the following XML to your application manifest file:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
    </application>
  </compatibility>

Add the following XML to your application configuration file:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
   <windowsSettings>
     <!-- The combination of below two tags have the following effect :
     1) Per-Monitor for >= Windows 10 Anniversary Update
     2) System < Windows 10 Anniversary Update -->
     <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
     <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
   </windowsSettings>
 </application>

Modify the appearance of a WebView

To constrain the display area, set the Width and Height properties.

This table contains links to each of these members.

Member Windows Forms WebView WPF WebView
Width property Width Width
Height property Height Height

Get the web page title

You can get the title of the HTML document currently displayed in the WebView by using the DocumentTitle property.

Input events and tab order

You can use the InvokeScriptAsync method with the JavaScript eval function to use the HTML event handlers, and use window.external.notify from the HTML event handlers to notify the application using the ScriptNotify event.

The WebView control has several APIs for basic navigation: GoBack, GoForward, Stop, Refresh, CanGoBack, and CanGoForward. You can use these to add typical web browsing capabilities to your app.

To set the initial content of the the WebView control, you can set the Source property in code, XAML, or in the Properties window. You can also use the Navigate methods to load content in code. Here's an example.

webView1.Navigate("http://www.contoso.com");

Respond to navigation events

The WebView control provides several events that you can use to respond to navigation and content loading states. The events occur in the following order for the root web view content:

  1. NavigationStarting

  2. ContentLoading

  3. DOMContentLoaded

  4. NavigationCompleted

The NavigationStarting event is raised before the web view navigates to new content. You can cancel navigation in a handler for this event by setting the WebViewNavigationStartingEventArgs.Cancel property to true.

webView1.NavigationStarting += webView1_NavigationStarting;

private void webView1_NavigationStarting(object sender, WebViewNavigationStartingEventArgs args)
{
    // Cancel navigation if URL is not allowed. (Implemetation of IsAllowedUri not shown.)
    if (!IsAllowedUri(args.Uri))
        args.Cancel = true;
}

The ContentLoading is raised when the web view has started loading new content.

webView1.ContentLoading += webView1_ContentLoading;

private void webView1_ContentLoading(WebView sender, WebViewContentLoadingEventArgs args)
{
    // Show status.
    if (args.Uri != null)
    {
        statusTextBlock.Text = "Loading content for " + args.Uri.ToString();
    }
}

The DOMContentLoaded event is raised when the web view has finished parsing the current HTML content.

webView1.DOMContentLoaded += webView1_DOMContentLoaded;

private void webView1_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
    // Show status.
    if (args.Uri != null)
    {
        statusTextBlock.Text = "Content for " + args.Uri.ToString() + " has finished loading";
    }
}

The NavigationCompleted event is raised when the web view has finished loading the current content or if navigation has failed. To determine whether navigation has failed, check the IsSuccess and WebErrorStatus properties of the event args.

webView1.NavigationCompleted += webView1_NavigationCompleted;

private void webView1_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
    if (args.IsSuccess == true)
    {
        statusTextBlock.Text = "Navigation to " + args.Uri.ToString() + " completed successfully.";
    }
    else
    {
        statusTextBlock.Text = "Navigation to: " + args.Uri.ToString() +
                               " failed with error " + args.WebErrorStatus.ToString();
    }
}

Similar events occur in the same order for each iframe in the web view content:

  1. The FrameNavigationStarting event is raised before a frame in the web view navigates to new content.

  2. The FrameContentLoading event is raised when a frame in the web view has started loading new content.

  3. The FrameDOMContentLoaded event is raised when a frame in the web view has finished parsing its current HTML content.

  4. The FrameNavigationCompleted event is raised when a frame in the web view has finished loading its content.

Respond to potential problems

You can respond to potential problems with the content such as long running scripts, content that the WebView control can't load, and warnings of unsafe content.

Your app might appear unresponsive while scripts are running. The LongRunningScriptDetected event is raised periodically while the web view executes JavaScript. This provides you with an opportunity to interrupt the script. To determine how long the script has been running, check the ExecutionTime property of the WebViewControlLongRunningScriptDetectedEventArgs. To halt the script, set the event args StopPageScriptExecution property to true. The halted script will not execute again unless it is reloaded during a subsequent web view navigation.

The web view control cannot host arbitrary file types. When an attempt is made to load content that the web view can't host, the UnviewableContentIdentified event occurs. You can handle this event and notify the user.

Similarly, the UnsupportedUriSchemeIdentified event occurs when a URI scheme that's not supported is invoked in the web content, such as fbconnect:// or mailto://. You can handle this event to provide custom behavior instead of allowing the default system launcher to launch the URI.

The UnsafeContentWarningDisplayingEvent event occurs when the web view shows a warning page for content that was reported as unsafe by the SmartScreen Filter. If the user chooses to continue the navigation, subsequent navigation to the page will not display the warning nor fire the event.

Handle special cases for web view content

You can use the ContainsFullScreenElement property and ContainsFullScreenElementChanged event to detect, respond to, and enable full-screen experiences in web content, such as full-screen video playback.

For example, you might use the ContainsFullScreenElementChanged event to resize the web view to occupy the entire app view, or, as the following example illustrates, put a windowed app in full screen mode.

// Assume webView is defined in XAML
webView.ContainsFullScreenElementChanged += webView_ContainsFullScreenElementChanged;

private void webView_ContainsFullScreenElementChanged(object sender, object args)
{
    var webview = sender as WebView;
    var applicationView = ApplicationView.GetForCurrentView();

    if (webview.ContainsFullScreenElement)
    {
        applicationView.TryEnterFullScreenMode();
    }
    else if (applicationView.IsFullScreenMode)
    {
        applicationView.ExitFullScreenMode();
    }
}

You can use the NewWindowRequested event to handle cases where hosted web content requests a new window, such as a popup window. You can use another WebView control to display the contents of the requested window.

Handle the PermissionRequested event to enable web features that require special capabilities. These currently include geolocation, IndexedDB storage, and user audio and video (for example, from a microphone or webcam).

In addition to the app handling the PermissionRequested event, the user will have to approve standard system dialogs for apps requesting location or media capabilities in order for these features to be enabled.

Here is an example of how an app would enable geolocation in a map from Bing:

// Assume webView is defined in XAML
webView.PermissionRequested += webView_PermissionRequested;

private void webView_PermissionRequested(WebView sender, WebViewPermissionRequestedEventArgs args)
{
    if (args.PermissionRequest.PermissionType == WebViewPermissionType.Geolocation &&
        args.PermissionRequest.Uri.Host == "www.bing.com")
    {
        args.PermissionRequest.Allow();
    }
}

If your app requires user input or other asynchronous operations to respond to a permission request, use the Defer method of WebViewControlPermissionRequest to create a WebViewControlDeferredPermissionRequest that can be acted upon at a later time.

Interact with web view content

You can interact with the content of the web view by using the InvokeScriptAsync method to invoke or inject script into the web view content, and the ScriptNotify event to get information back from the web view content.

To invoke JavaScript inside the web view content, use the InvokeScriptAsync method. The invoked script can return only string values.

For example, if the content of a web view named webView1 contains a function named setDate that takes 3 parameters, you can invoke it like this.

string[] args = {"January", "1", "2000"};
string returnValue = await webView1.InvokeScriptAsync("setDate", args);

You can use InvokeScriptAsync with the JavaScript eval function to inject content into the web page.

Here, the text of a XAML text box (nameTextBox.Text) is written to a div in an HTML page hosted in webView1.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    string functionString = String.Format("document.getElementById('nameDiv').innerText = 'Hello, {0}';", nameTextBox.Text);
    await webView1.InvokeScriptAsync("eval", new string[] { functionString });
}

Scripts in the web view content can use window.external.notify with a string parameter to send information back to your app. To receive these messages, handle the ScriptNotify event.

Options for web content hosting

You can use the Settings property (of type WebViewControlSettings to control whether JavaScript and IndexedDB are enabled. For example, if you use a web view to display strictly static content, you might want to disable JavaScript for best performance.

Creating multiple web views in the same process

By default, the WebView is hosted outside of your application's process in a process called WWAHost. When using the designer or default constructor, each new WebView is created in a new WWAHost instance, with its own copy of state. To share session cookies and state, consider using the same WWAHost process to host your WebView.

For Windows Forms Applications

For example, if through the designer a WebView named webView1 is on Form1, you can create a new WebView that shares the same process and state with webView1 like this.

Form1.cs

public partial class Form1 : Form
{
    private WebView webView2;

    public Form1()
    {
        InitializeComponent();

        // Assume webView created through the designer
        webView2 = new WebView(webView1.Process);
        ((ISupportInitialize)webView).BeginInit();
        // ... other initialization code
        ((ISupportInitialize)webView).EndInit();
    }
}

For WPF Applications

Similar to the Windows Forms example, if through the designer a WebView is created named WebView1 on the Window, you can create a new WebView that shares the same process and state with WebView1 like this.

MainWindow.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid x:Name="Grid1" Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

         <WPF:WebView x:Name="WebView1"
                      Grid.Row="0"
                      Grid.Column="0"
                      Loaded="WebView_Loaded" />
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void WebView_Loaded(object sender, RoutedEventArgs e)
    {
        var webView2 = new WebView(WebView1.Process);
        webView2.BeginInit();
        webView2.EndInit();

        Grid.SetRow(webView2, 0);
        Grid.SetColumn(webView2, 1);

        Grid1.Children.Add(webView2);
    }
}

Requirements

Device family .NET 4.6.2, Windows 10 (introduced v10.0.17110.0)
Namespace Windows Forms: Microsoft.Toolkit.Forms.UI.Controls
WPF: Microsoft.Toolkit.Wpf.UI.Controls
NuGet package Windows Forms: Microsoft.Toolkit.Forms.UI.Controls.WebView
WPF: Microsoft.Toolkit.Wpf.UI.Controls.WebView

API source code