When one thinks of WinForms, one does not generally think of the web at the same time, unless it’s how they wish they could move their app from one to the other. However, there’s a number of controls for displaying web pages in a WinForms app, and with .NET 5 we got a new one called WebView2.
The code in this post is available on GitHub, for you to use, extend, or just follow along while you read… and hopefully discover something new along the way!
I spent a couple evenings playing around and barely scratched the surface. Here’s what I learned.
What is WebView2?
The WebView2 control is, in their own words, a wrapper around the WebView2 COM API, which in a more general sense “allows you to embed web technologies (HTML, CSS, and JavaScript) in your native apps [using] Microsoft Edge as the rendering engine to display the web content”. Since Edge is based on Chromium (as are most major browsers), it’s effectively a wrapper around Chromium.
Basically, we get a Chromium-based browser in our app, similar to other third-party tools like CefSharp, DotNetBrowser, etc.
Initializing WebView2
The WebView2 control is available on NuGet. Just fire up a WinForms app, install the package, and (in VS2022 at least) it appears in the “Toolbox” fairly quickly. From there, we can drag and drop it onto a Form and we’re off the races…
Adding WebView2 to a WinForms project
After that, the control should be initialized: (maybe, probably.. read on)
|
|
Nearly everything on the WebView2 control is accessed through a CoreWebView2
property. Per the docs, that property is null
initially because creating it is an expensive operation, but in a little test app like this we want it right away. By calling EnsureCoreWebView2Async()
, the CoreWebView2
property is guaranteed to be initialized, so that subsequent calls won’t throw a null reference exception.
Navigate to a Website
Navigating to a site is super easy - just call the Navigate()
method. The only catch is it has to start with “https” or “http”:
|
|
Done! lol
Load Custom HTML
Alternatively, we can throw together some HTML on-the-fly (up to 2 MB) and pass that to the control instead, like this:
|
|
Or instead of including the CSS and JavaScript in the HTML, we can inject it separately with a call to AddScriptToExecuteOnDocumentCreatedAsync()
:
|
|
The “AddScript…” method runs before the HTML has actually been parsed, so I was getting javascript errors aplenty when I tried to access document.head
, document.getElementById()
, etc. Checking that the readyState for the document is “complete” seems to work. Probably a better way, who knows.
The last line of code is worth mentioning too, where I call RemoveScriptToExecuteOnDocumentCreated()
. Once a script is added, it’ll stick around and run again anytime a new document is loaded. To see what I mean, we can add something like this to the InitializeWebView2()
method:
|
|
Now the body and div on every page loaded has a light yellow background:
I remove the script so that it won’t load for the next page, but I have no clue what the best practices are around calling that. It seems to leave the scripts loaded as-is on the page just fine, but navigating back and forth breaks things, like the red text below that reverts back to black as I navigate around.
Like I said, barely scratching the surface here. 😄
Execute a Script
It’s super easy to execute a one-off script against the loaded document too:
|
|
No matter what page is loaded, it works the same:
Send Messages Back and Forth
It’s also possible to communicate between the loaded website and the Form
. We can subscribe to both events in the InitializeWebView2()
method, one a WinForms event, and the other a JavaScript event listener:
|
|
Now we can create some C# code that’ll send a message to our website…
|
|
… and some JS that’ll send messages back to our Form:
|
|
Now we can send messages back and forth:
Subscribe to Events
There’s all kinds of events we can subscribe to, like when navigation has started or completed, or the source in the control has changed (which is how I’m changing the text at the bottom of the Form in all the above images).
If you want the usual browser buttons, you can subscribe to those too:
|
|
I think that’s enough for now though!
Learn More
Microsoft has quite a bit of documentation to sift through, some of which I already linked to above. There’s tons of info on WebView2 in general, WebView2 in WinForms specifically, and a discussion forum on GitHub if you just need to vent.
If you found this content useful and would like to learn more, check out my Surviving WinForms repo, where you’ll find links to plenty more blog posts and practical examples!