默認菜單:
WebView2本身攜帶了類似Edge的右鍵菜單,但有的時候我們需要對它進行一些修改。
禁止dev菜單
webView.CoreWebView2.Settings.AreDevToolsEnabled = false;
禁止所有菜單
webView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
自定義菜單
自定義菜單我最初預想的實現的方式是:
-
屏蔽webview2本身的右鍵菜單
-
定義WPF控件的右鍵菜單
-
根據右鍵點擊的位置獲取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程序的顯示菜單的函數,實現起來可能更簡單些。