WebView2简单试用(八)—— 右键菜单

默认菜单:

WebView2本身携带了类似Edge的右键菜单,但有的时候我们需要对它进行一些修改。

禁止dev菜单

    webView.CoreWebView2.Settings.AreDevToolsEnabled = false;

禁止所有菜单

    webView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;

自定义菜单

自定义菜单我最初预想的实现的方式是:

  1. 屏蔽webview2本身的右键菜单
  2. 定义WPF控件的右键菜单
  3. 根据右键点击的位置获取WebView上下文信息,显示相应的菜单

然而,实现的时候遇到了一些麻烦:WPF的WebView2是吃掉了所有的鼠标右键事件的,根本无法显示WPF控件自定义的右键菜单,后来查阅了一下相关文章,一般实现的方式如下:

1. 首先定义脚本文档menu.js,该脚本的功能为:订阅右键菜单事件contextmenu,将位置信息发送给host程序,同时屏蔽本身的右键菜单。

document.addEventListener('contextmenu'function (event) {
let para =
    {
        Key: 'contextmenu',
        Pos:
        {
            X: event.x,
            Y: event.y,
        }
    };
    event.preventDefault();
    window.chrome.webview.postMessage(para);
});

2. Host程序在前端注入该js,并在接收到位置信息的时候显示自定义的右键菜单。

    var script = await File.ReadAllTextAsync(@"menu.js");
    await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script);

    webView.WebMessageReceived += (se) =>
    {
        var pos = JObject.Parse(e.WebMessageAsJson)["Pos"];

        menu.PlacementTarget  = webView;
        menu.IsOpen           = true;
        menu.Placement        = PlacementMode.Relative;
        menu.HorizontalOffset = pos["X"].Value<double>();
        menu.VerticalOffset   = pos["Y"].Value<double>();
    };

做到这一步时,已经可以在WPF程序中显示自己的右键菜单了。需要注意的是这里的contextmenu的显示方法。

实际应用场景中,往往需要根据上下文动态显示不同的菜单,这个就需要我们在contextmenu回调函数中传入更多的信息了,event参数是一个MouseEvent类型的对象,它本身就有不少属性可以直接传出来供我们使用。也可以通过document.elementFromPoint等js函数计算出上下文信息回传回来。

这里的关键点是contextmenu的上下文消息传递,我们也可以使用AddHostObjectToScript的方式嵌入回调函数代替webmessage的,再前端直接调用host程序的显示菜单的函数,实现起来可能更简单些。

参考文档:

原文地址:https://www.cnblogs.com/TianFang/p/14398424.html