I'm using a webview2-control in a winforms application. I use messages to communicate between c# and Javascript
- window.chrome.webview.addEventListener / window.chrome.webview.postMessage in Javascript
- event .CoreWebView2.WebMessageReceived and method CoreWebView2.PostWebMessageAsString in C#
The communication works BUT only after the page in webview2 has been somehow refreshed. The first message sent by c# is always ignored/not received by JS. The messages after that are correcly received and processed.
My UI code:
public GUI()
{
InitializeComponent();
browser.Source = new Uri(System.IO.Path.GetFullPath("HTML/ui.html"));
InitializeAsync();
}
async void InitializeAsync()
{
await browser.EnsureCoreWebView2Async(null);
browser.CoreWebView2.WebMessageReceived += MessageReceived;
}
void MessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
String content = args.TryGetWebMessageAsString();
if (content.StartsWith("getData"))
{
ReadDataFromCATIA();
var serializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects };
string jsonRootNode = JsonConvert.SerializeObject(this.RootNode, Formatting.Indented, serializerSettings); //here I've got the message I want to post
//String input = args.TryGetWebMessageAsString();
//MessageBox.Show("string from JS: " + input);
browser.CoreWebView2.PostWebMessageAsString(jsonRootNode);
}
else //object received
{
ProductNode received = JsonConvert.DeserializeObject<ProductNode>(content);
MessageBox.Show(received.PartNumber + " received");
}
}
and my JS in ui.html
window.chrome.webview.addEventListener('message', event => {
alert(event.data);
WriteDataFromCsharp(event.data);
});
function WriteDataFromCsharp(data) {
var target = document.getElementById('target');
if (target === null) { alert('target not found') };
//alert(target.id);
//target.textContent = event.data;
rootNode = JSON.parse(data);
target.innerHTML = addTable(rootNode); //addTable create an HTML table from the deserialized object rootNode
}
function RequestData() {
//function triggered by a button on the html page
//alert('post to c#');
window.chrome.webview.postMessage('getData');
}
So far, i've tried to:
- ensure the javascript is as late as possible in the page (defer, at the end of body). No changes.
- inject the javascript to the page after it has been loaded using .CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(jsCode). Same behavior.
- inject the javascript after once the event NavigationCompleted has fired. same behavior.
What do I miss ?
OnLoad()or theLoadhandler (making themasync) and subscribe toCoreWebView2InitializationCompleted. Some examples here: e.NewWindow = (CoreWebView2)sender still results in a separate instance and here: Which WebView2 event/function can be use to replace ScriptNotify Webview event? (slightly different language, same thing)window.chrome.webview.postMessage(). The JavaScript only adds an event listener that waits for messages sent by the host.WebMessageReceived? Or the event is raised, but the Document doesn't receive the post-back message from your App, so the listener ofmessagedoesn't trigger? --ReadDataFromCATIA();doesn't do anything here, but I assume you're calling that for a reason. After that, you're calling againargs.TryGetWebMessageAsString();, but that's supposed to containgetData. There's something else missing here. -- Remove the MessageBoxes, write to the Output Pane of VS instead.