6

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

 3 years ago
source link: https://www.cnblogs.com/TianFang/p/14398424.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

默认菜单:

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 += (s, e) =>
    {
        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程序的显示菜单的函数,实现起来可能更简单些。

参考文档:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK