3

I try to get the events click of html element. With a WebBrowser I used :

instance = Nothing
            instance = WebBrowser1.Document
            AddHandler instance.Click, AddressOf Document_Click

But with Webview2 I don't find the good practice. I must inject a javascript code ? But, how I get the handlder in C# or Vb.net application ?

Thanks a lot.

Here a sample code. I don't have the return in my function : WebView1_WebMessageReceived. Why ? I think, I forgot something....

Imports System.IO
Imports Microsoft.Web.WebView2.Core
Imports Newtonsoft.Json


    Class MainWindow
        Public Sub New()
    
            InitializeComponent()
            InitializeSyncroComponent()
    
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
    
        End Sub
    
        Structure JsonObject
            Public Key As String
            'Public Value As PointF
        End Structure
    
        Async Sub InitializeSyncroComponent()
            Await webview1.EnsureCoreWebView2Async
            webview1.CoreWebView2.Navigate("https://google.fr/")
        End Sub
    
        Private Sub WebView1_WebMessageReceived(ByVal sender As Object, ByVal e As Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs)
            Dim jsonObject As JsonObject = JsonConvert.DeserializeObject(Of JsonObject)(e.WebMessageAsJson)
    
            Select Case jsonObject.Key
                Case "contextmenu"
                    'contextMenuStrip1.Show(Point.Truncate(jsonObject.Value))
                Case "mousedown"
                    Stop
                    ' contextMenuStrip1.Hide()
            End Select
        End Sub
    
        Private Sub webview1_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles webview1.NavigationCompleted
            webview1.CoreWebView2.Settings.AreDefaultContextMenusEnabled = False
            Dim script As String = File.ReadAllText("d:\test_mouse.js")
            webview1.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script)
        End Sub
    End Class

Script Java:

document.addEventListener('mousedown', function (event)
{
    let jsonObject =
    {
        Key: 'mousedown',
        Value:
        {
            X: event.screenX,
            Y: event.screenY
        }
    };
    window.chrome.webview.postMessage(jsonObject);
});

Edit: I found my error... it was really not much !

I had forgot the déclaration of the WebMessageReceived in the webview property.

Webview Property

Poul Bak
  • 10,450
  • 5
  • 32
  • 57
  • Does this answer your question? [How do you override the ContextMenu that appears when right clicking on WebView2 Control?](https://stackoverflow.com/questions/62624373/how-do-you-override-the-contextmenu-that-appears-when-right-clicking-on-webview2) – Poul Bak Dec 18 '20 at 10:13
  • You have not added the event handler (in VB.Net). Also, you want to change `mousedown` to `click` (all places - in both VB code and javascript). Now you should get an event when clicked. – Poul Bak Dec 19 '20 at 21:05
  • Thank you very much for your response. I added the event handler, but I don't sure of the syntaxe. I added : "AddHandler webview1.CoreWebView2.WebMessageReceived, AddressOf WebView1_WebMessageReceived". But I have an error. Can you help me ? – François HEBERT Dec 19 '20 at 23:17
  • I can't guess, show the error and where in the code you get it. – Poul Bak Dec 20 '20 at 10:44
  • Just noticed: You have commented out the `Value` from the structure - then you must also comment out the `Value` from javascript. – Poul Bak Dec 20 '20 at 10:52
  • Th error is : System.NullReferenceException HResult=0x80004003 Message = Object reference is not set to an instance of an object. I removed the comment. My purpose is to get Id or name id of a element when I click on it. So I should to change the js code. – François HEBERT Dec 21 '20 at 11:49
  • You really need to learn how to DEBUG code. Add Breakpoints and step through your code, inspect values until you get an error. Then tell us, where the error is - only then can we help you. – Poul Bak Dec 21 '20 at 17:03

2 Answers2

10

Ok, I don't know VB.Net, but you seem to be able to translate C# code, so I will try to create a simple working solution in C#:

First, download Microsoft.Web.WebView2and Newtonsoft.Json from Nuget and install in your project (you have probably already done that).

Now drop the WebView2 on the form - then in Property Inspector:

  1. Set the source to: 'https://google.fr/'

  2. doubleclick CoreWebView2InitializationCompleted and WebMessageReceived events to create skeletons in your code.

Now add this code translated to VB.Net:

using Microsoft.Web.WebView2.Core;
using Newtonsoft.Json;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public struct JsonObject
        {
            public string Key;
            public string Value;
        }

        private async void WebView21_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            string script = File.ReadAllText("Mouse.js");
            await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);
        }

        private void WebView21_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
        {
            JsonObject jsonObject = JsonConvert.DeserializeObject<JsonObject>(e.WebMessageAsJson);
            switch (jsonObject.Key)
            {
                case "click":
                    MessageBox.Show(jsonObject.Value);
                    break;

            }
        }
    }
}

Now create a javascript file ('Mouse.js') in your project directory, select the file and in Property Inspector select Copy to output directory and choose: Copy if newer. That means, your javascript file can be found by your VB program using the relative link.

Now paste the following javascript into the file:

document.addEventListener('click', function (event)
{
    let elem = event.target;
    let jsonObject =
    {
        Key: 'click',
        Value: elem.name || elem.id || elem.tagName || "Unkown"
    };
    window.chrome.webview.postMessage(jsonObject);
});

Now, when you run it you should get a messagebox showing either Name, ID or Tag Name of the element you click (in that order).

The reason I use the Key: 'click'approach is that when you later want to detect for instance MouseDown you can easily add that key - then you can detect both (Otherwise you could only detect one kind of event).

Update:

Changed CoreWebView2Readyevent to CoreWebView2InitializationCompleted. That's the new name for the event. It uses CoreWebView2InitializationCompletedEventArgsas eventArgs.

Poul Bak
  • 10,450
  • 5
  • 32
  • 57
1

Update for new Microsoft namespaces:

using System.Text.Json;
using System.Text.Json.Serialization;
    private void WebView_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
    {
        JsonObject jsonObject = JsonSerializer.Deserialize<JsonObject>(e.WebMessageAsJson);
        switch (jsonObject.Key)
        {
            case "click":
                MessageBox.Show(jsonObject.Value);
                break;

        }
    }