Calling WinUI from Blazor App Hosted in WebView2
In the previous blog post you learned how you can use JavaScript Interop to call from your WinUI application into your Blazor application that you host in the WinUI app in a WebView2
. So, this was just the direction WinUI to Blazor.
But can you also call from the hosted Blazor app into your WinUI app?
Of course you can. To show you how it works, I’ve extended the application from the previous blog post. I’ve added an “Update WinUI from Blazor”–Button
in the Blazor app, you see it in the screenshot below. When you click this Button
, the WinUI TextBox
is set to the firstname entered in the Blazor input field.

To achieve this, you can send messages from the hosted web app to the WinUI WebView2
. Let’s see how this works.
WinUI: The WebMessageReceived Event
In the WinUI app, let’s register an event handler for the WebView2
‘s WebMessageReceived
event like below (The three dots … mean that there’s code that I didn’t include in the snippet below. But you find the complete code on GitHub):
public sealed partial class MainPage : Page
{
public MainPage()
{
...
webView2.WebMessageReceived += WebView2_WebMessageReceived;
}
...
private void WebView2_WebMessageReceived(WebView2 sender,
WebView2WebMessageReceivedEventArgs args)
{
txtFirstName.Text = args.WebMessageAsString;
}
}
As you can see in the code snippet above, the WebView2WebMessageReceivedEventArgs
have a WebMessageAsString
property. This property contains the received message.
With this code, our WinUI app is ready to receive a string from the Blazor app, so let’s continue in the Blazor app.
Blazor: Set up the JavaScript Code
To send a message from Blazor, you need to execute JavaScript code. The function that you need to execute to send a message is called window.chrome.webview.postMessage
. When you call that function from JavaScript, the WebMessageReceived
event will be raised on the WinUI app’s WebView2
. That means, we just need to call that function from Blazor with the firstname value.
In the Blazor app’s wwwroot
folder, I’ve created already in the previous blog post a JavaScript file with an interopFunctions
object. Now, let’s add a setFirstNameInWinUI
method to that interopFunctions
object like below:
interopFunctions.setFirstNameInWinUI = (firstName) => {
window.chrome.webview.postMessage(firstName);
};
As you can see, that interopFunctions.setFirstNameInWinUI
method is just a wrapper around the window.chrome.webview.postMessage
function. The firstName parameter is passed as an argument to the postMessage
function. Now we need to call it from Blazor.
Blazor: Call the JavaScript Code
In the Index.razor
component I’ve added a button and an event handler for the button’s click event. You can see that code in the snippet below. The event handler is called SetFirstNameInWinUI
. In that SetFirstNameInWinUI
method, the IJSRuntime
is used to call the interopFunctions.setFirstNameInWinUI
JavaScript method that you saw in the previous snippet. The firstName field of the Blazor component is passed as an argument to that JavaScript method.
<button class="btn btn-secondary" @onclick="SetFirstNameInWinUI">
Update WinUI from Blazor
</button>
@code{
private string firstName = "Julia";
private async Task SetFirstNameInWinUI()
{
await JSRuntime.InvokeVoidAsync("interopFunctions.setFirstNameInWinUI",
firstName);
}
That’s it. Now when you click the “Update WinUI from Blazor” Button in the Blazor App, the firstname TextBox in the WinUI app is updated. Great!
Sending Different Messages
In this blog post we were just sending a single message with the firstname from Blazor to the WinUI app. That was easy. But what if you have different messages that you want to send to your WinUI app?
There is just one WebMessageReceived
event on the WebView2
. To send different messages, you need to have a kind of switch logic in the event handler of that WebMessageReceived
event, and that means from JavaScript you need to pass information that allows you to switch in the WinUI app.
Let’s look at an example. The following snippet shows an adjusted setFirstNameInWinUI
JavaScript method. Instead of a simple firstname string, it passes a JSON string to the postMessage
function. That JSON string contains a JSON object with the properties messageType
and value
:
interopFunctions.setFirstNameInWinUI = (firstName) => {
window.chrome.webview.postMessage(JSON.stringify({
messageType: 'firstName',
value: firstName
}));
};
Now in the WinUI app, you can define a WebMessage
class that has these two properties:
class WebMessage
{
public string MessageType { get; set; }
public string Value { get; set; }
}
In the WebMessageReceived
handler of the WebView2
you can now deserialize the received JSON string to a WebMessage
object. In the code below I use NewtonSoft’s JsonConvert
class. After deserializing the JSON string, you can check on the WebMessage
object the MessageType
and use the Value
. In the case below, the code checks if it’s the firstName message type, and if that’s the case, the value is assigned to the Text
property of the firstName TextBox:
private void WebView2_WebMessageReceived(WebView2 sender,
WebView2WebMessageReceivedEventArgs args)
{
var jsonString = args.WebMessageAsString;
var message= JsonConvert.DeserializeObject<WebMessage>(jsonString);
if(message.MessageType == "firstName")
{
txtFirstName.Text = message.Value;
}
}
That’s it! Now you could send other string messages to your Blazor app and switch by the message type.
Go and grab the code from GitHub.
Summary
Now you’ve seen the Blazor to WinUI communication. In the previous blog post you learned about the WinUI to Blazor communication. That means that you can communicate in both directions, and this makes the integration of Blazor apps and components in WinUI via WebView2 really powerful.
Happy coding!
Thomas
Comments (4)
[…] Calling WinUI from Blazor App Hosted in WebView2 (Thomas Claudius Huber) […]
This is very interesting and may be useful in certain Interop scenarios.
Yes Tony, it could be interesting if you have a Blazor component that you want to re-use.
Very interesting Thomas! I wonder if in a medium sized application I could implement the UI entirely via a JavaScript framework in WebView2 (e.g. Vue.js). Unfortunately I can’t find any sources about patterns for this approach. The interface to the desktop application would then only be implemented via events and not as in WPF and co via classic binding or? Will WebView be developed further or how future-proof would this approach be?