Quantcast
Channel: Dev Blog - Johan Danforth
Viewing all articles
Browse latest Browse all 43

WebView2 Getting Started

$
0
0

The Microsoft WebView2 control allows you to embed Web Tech in native applications. It’s miles better than the old web browser controls. The WebView2 control is based on the Chromium platform.

The official docs for the control are found here: https://docs.microsoft.com/en-us/microsoft-edge/webview2/

Pre-reqs

Important note (as of 2021-01-20) - ensure you installed the following list of pre-requisites before proceeding:

I suggest you visit https://www.microsoftedgeinsider.com/download and get the “Edge Canary Channel” that way.

Install WebView2 SDK in Visual Studio

Once you’ve created your WebForms or WPF project, install the Microsoft.Web.WebView2 package from Nuget:

PM> Install-Package Microsoft.Web.WebView2

Initializing WebView2 Control

Much about the control is asynchronous, and to make sure the control is loaded and ready, add an InitializeAsync() method to your form constructor, and place the events of interest there, like so:

publicwebView2TestForm()
        {
            InitializeComponent();
            InitializeAsync();
        }asyncvoidInitializeAsync()
        {
            webViewControl.NavigationCompleted += WebViewControlOnNavigationCompleted;
            webViewControl.WebMessageReceived += WebViewControlOnWebMessageReceived;await webViewControl.EnsureCoreWebView2Async(null);
        }

Send Message to Web Page

Easiest way to communicate between the web page and the native application is to send messages. From the native app:

webViewControl.CoreWebView2.PostWebMessageAsString("proxy.object.added");

To handle messages, the web page need some scripting:

        window.chrome.webview.addEventListener('message',event => {
                console.log('Got message from host!');
                console.log(event.data);
                handleMessages(event.data);
            });

Send Message to Host

To send a message from the web page

window.chrome.webview.postMessage('page.ready');

To handle messages from web page in the host:

privatevoidWebViewControlOnWebMessageReceived(objectsender, CoreWebView2WebMessageReceivedEventArgs e)
        {varmessage = e.TryGetWebMessageAsString();switch (message)
            {case"page.ready":
                    Trace.TraceInformation("Got page.ready message!");break;default:
                    Trace.TraceWarning("Unknown message received: " + message);break;
            }
        }

Proxy Objects

One of the coolest features availeble is to send a “proxy object” from the native application to the web page. There are some limitations but powerful enough. The best info I’ve found is this: https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addhostobjecttoscript 

The class/object must be exposed as a COM object (!):

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]publicclassProxyHostObject
    {// sample propertypublicstring Name { get; set; } = "Johan";// sample methodpublicstringGetName()
        {return Name;
        }// sample indexed property
        [System.Runtime.CompilerServices.IndexerName("Items")]publicstringthis[intindex]
        {get => _dictionary[index];set => _dictionary[index] = value;
        }private Dictionary<int, string> _dictionary = new Dictionary<int, string>();
    }

The use of the ClassInterface attribute is discussed in the Edge github repo, because the AutoDual value is not recommended in the docs, and even deprecated in dotnet:

Using AutoDual is strongly discouraged because of the versioning limitations described in System.Runtime.InteropServices.ClassInterfaceAttribute.

The issue is discussed here: https://github.com/MicrosoftEdge/WebView2Feedback/issues/517

To create and use the proxy object in the web page:

asyncfunction handleMessages(message) {switch (event.data) {case'proxy.object.added':
            {const obj = window.chrome.webview.hostObjects.proxyobject;
                console.log(obj);var name1 = await obj.Name;
                console.log('name prop: ' + name1);var name2 = await obj.GetName();
                console.log('name func: ' + name2);

                obj.GetName().then(name => {
                    console.log("GetName promise name: " + name);
                });// Indexed propertieslet index = 123;
                obj[index] = "test";let result = await obj[index];
                console.log(result);
            }break;default:
            console.log("unknown message: " + event.data);
        }
    }

Viewing all articles
Browse latest Browse all 43

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>