Here's a complete code example using NuGet package Microsoft.Web.WebView2 (v. 1.0.721-prerelease). See the Webview2 Release Notes for requirements.
Resources:
Note: This example will be using WinForms--Windows Forms App (.NET Framework). When using .NET Framework, versions >= 4.6.2 are supported (previously version 4.6.2 or greater was required. However, if one looks at the NuGet package folders, it appears that the required minimum version may now be 4.5. See the release notes for more information). See the documentation for other supported SDKs.
Visual Studio versions 2017 and 2019 are supported. If you don't have either, you may be able to Download Visual Studio Community -- which is free.
Download and install Microsoft Edge Dev (aka "Dev Channel"): Microsoft Edge Insider Channels -- see documentation for other options.
Open Visual Studio - (2017 or 2019)
Set Default package management format to PackageReference (this is optional, but recommended). See Migrate from packages.config to PackageReference for more information.
2019:
- Click Continue without code
- In Visual Studio (VS) menu, click
Tools
- Select Options
- Expand NuGet Package Manager
- Click General
- Under Package Management, set
Default package management format:
to PackageReference
2017:
- In Visual Studio (VS) menu, click
Tools
- Select Options
- Expand NuGet Package Manager
- Click General
- Under Package Management, set
Default package management format:
to PackageReference
Create New Project
2019:
- In VS menu, click File
- Select New
- Select Project
- Optional: Use the following options to limit displayed selections: C#
Windows Desktop
- Click Windows Forms App (.NET Framework)
- Click Next
- Enter a name for you project (ex: WebView2Test), select desired location, and set Framework to a version >= 4.6.2
- Click Create
2017:
- In VS menu, click File
- Select New
- Select Project
- Expand Visual C#
- Click Windows Desktop
- Click Windows Forms App (.NET Framework)
- Enter a name for you project (ex: WebView2Test), select desired location, and set Framework to a version >= 4.6.2
- Click OK
Add Microsoft.Web.WebView2 NuGet package to project (2019/2017)
- In VS menu, click View
- Select Solution Explorer
- In Solution Explorer, right-click <project name>
- Select Manage NuGet
Packages...
- Click Browse
- Check Include prerelease
- Search: Microsoft.Web.WebView2
- Select Version 1.0.721-prerelease
- Set any desired options by clicking the down-arrow next to the left of
"Options" to show the available options (ie: Install and Update options
and Uninstall options)
- Click Install
- If a window pops up, click OK
Optional: Add MenuStrip to Form (Form1)
- In Solution Explorer, click Form1.cs to select it
- In VS menu, click View
- Select Toolbox
- Expand All Windows Forms
- Select MenuStrip
- Click on Form (Form1) to add the control to the Form
Optional: Add StatusStrip to Form (Form1)
- In Solution Explorer, click Form1.cs to select it
- In VS menu, click View
- Select Toolbox
- Expand All Windows Forms
- Select StatusStrip
- Click on Form (Form1) to add the control to the Form
Add SplitContainer to Form (Form1)
- In Solution Explorer, click Form1.cs to select it
- In VS menu, click View
- Select Toolbox
- Expand All Windows Forms
- Select SplitContainer
- Click on Form (Form1) to add the control to the Form
Add button to left panel of SplitContainer (splitContainer1)
- In Solution Explorer, click Form1.cs to select it
- In VS menu, click View
- Select Toolbox
- Expand All Windows Forms
- Select Button
- Click on Form (Form1) to add the control to the Form. If necessary, move the button to the left panel (panel1) of the SplitContainer.
Change button properties
- In VS menu, click View
- Select Properties Window
- In Properties Window, use the drop-down to select the button (button1)
- Change (Name) to the desired name (ex: btnClickJSButton)
- Change text to desired text (ex: Click JS Button)
Add WebView2 control to SplitContainer (panel2)
- In Solution Explorer, click Form1.cs to select it
- In VS menu, click View
- Select Toolbox
- Expand WebView2 Windows Forms Control
Note: If "WebView2 Windows Forms Control" isn't in the Toolbox, right-click in an open space in the Toolbox, and select "Choose Items". Then click "Browse". Go to %UserProfile%.nuget\packages\microsoft.web.webview2\1.0.721-prerelease\lib\net45 (ex: C:\Users\<username>\.nuget\packages\microsoft.web.webview2\1.0.721-prerelease\lib\net45). Choose "Microsoft.Web.WebView2.WinForms.dll"
- Select WebView2
- Click on Form (Form1) to add the control to the Form. If necessary, move the WebView2 control to the right panel (panel2) of the SplitContainer.
Change WebView2 properties
- In Properties Window, use the drop-down to select the WebView2 control instance (webView21)
- Set Dock property to Fill
Add Load event handler to Form (Form1)
- In Solution Explorer, click Form1.cs to select it
- Double-click the top of the Form, which will add the event handler: Form1_Load
Add Button click event handler
- In Solution Explorer, click Form1.cs to select it
- On the Form (Form1), double-click the button (btnClickJSButton), to create the click event handler (btnClickJSButton_Click)
Create a folder for HTML code
- In Solution Explorer, right-click <project name>
- Select Add
- Select New Folder. The folder will be selected. If not, right-click the folder and select "Rename". Set the name to "HTML".
Create index.html
- In Solution Explorer, right-click <project name>
- Right-click HTML folder
- Select Add
- Select New Item
- Click HTML Page (Name: index.html)
- Click Add
Change index.html property
- In Solution Explorer, click index.html to select it
- In Properties Window, set Build Action to Embedded Resource
Add code to: index.html
index.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script>
function btnClickAction(name) {
alert('button ' + name + ' was clicked');
}
</script>
</head>
<body>
<button type="button" class="size-grid-button" id="size-grid-button1" onclick="btnClickAction('size-grid-button1')">Click Me 1</button>
<button type="button" class="size-grid-button" id="size-grid-button2" onclick="btnClickAction('size-grid-button2')">Click Me 2</button>
<button type="button" class="size-grid-button" id="size-grid-button3" onclick="btnClickAction('size-grid-button3')" value="Click Me 3">Click Me 3</button>
<input type="button" class="size-grid-button" id="size-grid-button4" onclick="btnClickAction('size-grid-button4')" value="Click Me 4" />
</body>
</html>
Create a folder for JavaScript code
- In Solution Explorer, right-click <project name>
- Select Add
- Select New Folder. The folder will be selected. If not, right-click the folder and select "Rename". Set the name to "JavaScript".
Create TestButtonClick.js
- In Solution Explorer, right-click <project name>
- Right-click JavaScript folder
- Select Add
- Select New Item
- Click JavaScript File (Name: TestButtonClick.js)
- Click Add
Change TestButtonClick.js property
- In Solution Explorer, click TestButtonClick.js to select it
- In Properties Window, set Build Action to Embedded Resource
Option 1 (desired HTML element is 'button')
Example:
<button type="button" class="size-grid-button" id="size-grid-button1" onclick="btnClickAction('size-grid-button1')">Click Me 1</button>
Add code to: TestButtonClick.js
TestButtonClick.js (Option 1)
function clickDesiredButtonByInnerText(btnInnerText) {
//let buttons = document.getElementByTagName('button');
let buttons = document.querySelectorAll('button');
let i = 0;
let result = null;
if (buttons) {
for (i = 0; i < buttons.length; i++) {
//window.chrome.webview.postMessage("button[" + i + "].innerText: " + buttons[i].innerText);
if (buttons[i].innerText === btnInnerText) {
buttons[i].click();
result = btnInnerText + ' clicked';
break; //exit loop
}
}
}
//window.chrome.webview.postMessage("result:" + result);
return result;
}
Option 2 (desired HTML element is 'input')
Example:
<input type="button" class="size-grid-button" id="size-grid-button4" onclick="btnClickAction('size-grid-button4')" value="Click Me 4" />
Add code to: TestButtonClick.js
TestButtonClick.js (Option 2)
function clickDesiredInputButtonByTextValue(btnValue) {
let i = 0;
let result = null;
buttons = document.querySelectorAll('input');
if (buttons) {
for (i = 0; i < buttons.length; i++) {
//window.chrome.webview.postMessage("button[" + i + "].value: " + buttons[i].value + ' type: ' + buttons[i].type);
if (buttons[i].type === 'button' && buttons[i].value === btnValue) {
buttons[i].click();
result = btnValue + ' clicked';
break; //exit loop
}
}
}
//window.chrome.webview.postMessage("result:" + result);
return result;
}
Option 3 (desired HTML element is ('button' OR 'input') AND element has an 'id' attribute that has a unique value)
Add code to: TestButtonClick.js
TestButtonClick.js (Option 3)
function clickDesiredButtonById(btnId) {
let result = null;
let desiredButton = document.getElementById(btnId);
if (desiredButton) {
desiredButton.click();
result = 'button with id = ' + btnId + ' clicked';
}
//window.chrome.webview.postMessage("result:" + result);
return result;
}
Create a new class (HelperLoadResource.cs)
- In Solution Explorer, right-click <project name>
- Select Add
- Select Class... (Name: HelperLoadResource.cs)
Add using statements (HelperLoadResource.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Diagnostics;
Add code to: HelperLoadResource.cs
Note: HelperLoadResource.ReadResource
will read text from the embedded files (HTML and JavaScript) and put the text into a string variable.
HelperLoadResource.cs
public static class HelperLoadResource
{
public static string ReadResource(string filename)
{
//use UTF8 encoding as the default encoding
return ReadResource(filename, Encoding.UTF8);
}
public static string ReadResource(string filename, Encoding fileEncoding)
{
string fqResourceName = string.Empty;
string result = string.Empty;
//get executing assembly
Assembly execAssembly = Assembly.GetExecutingAssembly();
//get resource names
string[] resourceNames = execAssembly.GetManifestResourceNames();
if (resourceNames != null && resourceNames.Length > 0)
{
foreach (string rName in resourceNames)
{
if (rName.EndsWith(filename))
{
//set value to 1st match
//if the same filename exists in different folders,
//the filename can be specified as <folder name>.<filename>
//or <namespace>.<folder name>.<filename>
fqResourceName = rName;
//exit loop
break;
}
}
//if not found, throw exception
if (String.IsNullOrEmpty(fqResourceName))
{
throw new Exception($"Resource '{filename}' not found.");
}
//get file text
using (Stream s = execAssembly.GetManifestResourceStream(fqResourceName))
{
using (StreamReader reader = new StreamReader(s, fileEncoding))
{
//get text
result = reader.ReadToEnd();
}
}
}
return result;
}
}
Add code to: Form1.cs
- In Solution Explorer, click <project name>
- Right-click Form1.cs
- Select View Code
Add using statements (Form1.cs):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System.Diagnostics;
Add method InitializeCoreWebView2Async
(Form1.cs)
InitializeCoreWebView2Async (Form1.cs)
private async Task InitializeCoreWebView2Async()
{
//initialize CorewWebView2
await webView21.EnsureCoreWebView2Async();
}
Add code to: Form1_Load
(Form1.cs)
Note: Add the async
keyword to Form_Load
.
Form1_Load (Form1.cs)
private async void Form1_Load(object sender, EventArgs e)
{
//show MS Edge version -- also ensures that an exception will be raised if proper MS Edge version isn't installed
Debug.WriteLine(CoreWebView2Environment.GetAvailableBrowserVersionString());
//initialized CorewWebView2
await InitializeCoreWebView2Async();
//get HTML
string html = HelperLoadResource.ReadResource("index.html");
//display HTML in WebView2
webView21.NavigateToString(html);
}
Subscribe to WebView2 CoreWebView2InitializationCompleted
event
- In Properties Window, use the drop-down to select the WebView2 instance (webView21)
- Click the orange lightning bolt to see available events
- Double-click CoreWebView2InitializationCompleted to add the event handler to the Form (Form1.cs)
Add the following code to CoreWebView2InitializationCompleted
CoreWebView2InitializationCompleted (Form1.cs)
private void webView21_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
//subscribe to CoreWebView2 events (add event handlers)
webView21.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
}
CoreWebView2_WebMessageReceived (Form1.cs)
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
Debug.WriteLine("Info: MSG (JSON): " + e.WebMessageAsJson);
Debug.WriteLine("Info: MSG (String): " + e.TryGetWebMessageAsString());
}
If using Option 1 above (desired HTML element is 'button'), add method ClickWebView2ButtonByInnerText
ClickWebView2ButtonByInnerText (Form1.cs)
private async Task ClickWebView2ButtonByInnerText(string btnInnerText)
{
if (webView21 != null && webView21.CoreWebView2 != null)
{
string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
jsCode += System.Environment.NewLine;
jsCode += "clickDesiredButtonByInnerText('" + btnInnerText + "');";
var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);
Debug.WriteLine("result: " + result);
}
}
Add the following code to the Button click event handler btnClickButton_Click
(Option 1)
Note: Add the async
keyword.
private async void btnClickButton_Click(object sender, EventArgs e)
{
await ClickWebView2ButtonByInnerText("Click Me 3");
}
If using Option 2 above (desired HTML element is 'input'), add method ClickWebView2InputButton
ClickWebView2InputButton (Form1.cs)
private async Task ClickWebView2InputButton(string btnValue)
{
if (webView21 != null && webView21.CoreWebView2 != null)
{
string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
jsCode += System.Environment.NewLine;
jsCode += "clickDesiredInputButtonByTextValue('" + btnValue + "');";
var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);
Debug.WriteLine("result: " + result);
}
}
Add the following code to the Button click event handler btnClickButton_Click
(Option 2)
Note: Add the async
keyword.
private async void btnClickButton_Click(object sender, EventArgs e)
{
await ClickWebView2InputButton("Click Me 4");
}
If using Option 3 above (desired HTML element is ('button' OR 'input') AND element has an 'id' attribute that has a unique value), add method ClickWebView2ButtonById
ClickWebView2ButtonById (Form1.cs)
private async Task ClickWebView2ButtonById(string btnId)
{
if (webView21 != null && webView21.CoreWebView2 != null)
{
string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
jsCode += System.Environment.NewLine;
jsCode += "clickDesiredButtonById('" + btnId + "');";
var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);
Debug.WriteLine("result: " + result);
}
}
Add the following code to the Button click event handler btnClickButton_Click
(Option 3)
Note: Add the async
keyword.
private async void btnClickButton_Click(object sender, EventArgs e)
{
await ClickWebView2ButtonById("size-grid-button2");
await ClickWebView2ButtonById("size-grid-button4");
}
Run the program.
Click the button on the form to test.
Additional Resources