Skip to main content

Using widgets with Windows Forms (.NET)

In this tutorial, you'll learn how to easily integrate widgets into Windows Forms, using the WatchList widget as an example. Let's create a simple widget component.

Creating web page

First of all, we need to make a widget page to have something to integrate into Windows Forms. To make it we can follow the guide about integration widgets by CDN. We will skip details and make just simple page with one widget only, with WatchList:

index.html
<!DOCTYPE html>
<html lang="en">
<body>
<div id="widget"></div>
<script type="module">
import { newWatchListWidget } from 'https://path-to-cdn/widgets/watch-list.js'
const initWidget = (dataProviders) => {
const container = document.getElementById('widget')
const widget = newWatchListWidget({
element: container,
providers: dataProviders,
state: {
symbols: ['AAPL', 'MSFT', 'TSLA'],
columns: ['symbol', 'lastPrice', 'askPrice', 'bidPrice', 'dayVolume'],
columnSizes: {},
filters: {},
},
theme: 'light',
})
}
window.initWidget = initWidget
</script>
</body>
</html>

You can see that we provide method initWidget to global window object, to be able to call it from Windows Forms side. This code we have to save as index.html and place it in the directory with the application executable for the following steps

Windows Forms

Now it needs to create Windows Forms application and we hope that you know how to work with Windows Forms applications. However, it needs to be mentioned, that we will create application with .NET 6.0 and with Microsoft.Web.WebView2 NuGet package. As result, you have to see something like that in your .csproj file:

ProjectName.csproj
<ItemGroup>
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2420.47" />
</ItemGroup>

Next, you need to find WebView2 control and add to the form

Main application logic

Before moving to the final step we need to describe our data providers, which will be used by widget. It is key values to be connected to certain resources with certain access. Let's create a file named as dataProviders.json and place it in the directory with the application executable:

dataProviders.json
{
"ipfPath": "/your-path/ipf",
"ipfAuthHeader": "your-header",
"feedPath": "wss://your-path/feed",
"feedAuthHeader": "your-header",
"fundamentalsPath": "/api/fundamentals",
"fundamentalsAuthHeader": "your-header",
"schedulePath": "/api/schedule"
}

After describing data providers we have finished all preparation stages, and we can move to our form .cs file and replace the code with the following:

Form1.cs
using Microsoft.Web.WebView2.Core;

namespace WatchList
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_ = InitializeAsync();
}
private async Task InitializeAsync()
{
// Disabled security to avoid issues with CORS politics
var options = new CoreWebView2EnvironmentOptions("--disable-web-security");
var environment = await CoreWebView2Environment.CreateAsync(null, null, options);
await webView21.EnsureCoreWebView2Async(environment);
// Subscribe to NavigationCompleted event
webView21.NavigationCompleted += WebView_NavigationCompleted;
// Sets a mapping between a virtual host name and a folder path to make available to web sites via that host name.
webView21.CoreWebView2.SetVirtualHostNameToFolderMapping("local", ".", CoreWebView2HostResourceAccessKind.Allow);
// Calling created index.html web page
webView21.CoreWebView2.Navigate("https://local/index.html");
}
private void WebView_NavigationCompleted(
object sender,
CoreWebView2NavigationCompletedEventArgs e
)
{
// Reading data providers
var dataProviders = File.ReadAllText("dataProviders.json");
// Calling "initWidget" method to init our WatchList widget with specified data providers
webView21.CoreWebView2.ExecuteScriptAsync($"window.initWidget({dataProviders})");
}
}
}

That's it. After building the project you have to see WatchList widget inside the Form

Communication with widget

If you want to have something more than just readonly widget you can read the guide about linking widgets to understand main concepts of reading and updating widget state. But then you need to be able to call these methods from the Windows Forms side. And you can find all necessary information in official WebView documentation. Shortly, you can listen events from .NET side by adding listeners like that:

window.chrome.webview.addEventListener('message', (arg) => {
// Your logic here. Setting widget symbol, for example
})

If you want to push a message to .NET side, you can call the next method:

window.chrome.webview.postMessage('any value as text')

Debug

During developing the application, you can probably face with issues inside the WebView. To debug it, you can add the next code to InitializeAsync method:

MainForm.cs
private async Task InitializeAsync()
{
var options = new CoreWebView2EnvironmentOptions("--disable-web-security");
var environment = await CoreWebView2Environment.CreateAsync(null, null, options);
await webView21.EnsureCoreWebView2Async(environment);
webView21.CoreWebView2.OpenDevToolsWindow();
}