CefSharp 自定义右键菜单 (Winform版)
作者:admin 日期:2022-10-24
- /* 引用
- using CefSharp;
- using CefSharp.WinForms;
- using System;
- using System.Collections.Generic;
- */
- public class MenuHandler : IContextMenuHandler
- {
- void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
- {
- //主要修改代码在此处;如果需要完完全全重新添加菜单项,首先执行model.Clear()清空菜单列表即可.
- //需要自定义菜单项的,可以在这里添加按钮;
- if (model.Count > 0)
- {
- model.AddSeparator();//添加分隔符;
- }
- model.AddItem((CefMenuCommand)26501, "Show DevTools");
- model.AddItem((CefMenuCommand)26502, "Close DevTools");
- }
- bool IContextMenuHandler.OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
- {
- //命令的执行,点击菜单做什么事写在这里.
- if (commandId == (CefMenuCommand)26501)
- {
- browser.GetHost().ShowDevTools();
- return true;
- }
- if (commandId == (CefMenuCommand)26502)
- {
- browser.GetHost().CloseDevTools();
- return true;
- }
- return false;
- }
- void IContextMenuHandler.OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
- {
- var webBrowser = (ChromiumWebBrowser)browserControl;
- Action setContextAction = delegate ()
- {
- webBrowser.ContextMenu = null;
- };
- webBrowser.Invoke(setContextAction);
- }
- bool IContextMenuHandler.RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
- {
- //return false 才可以弹出;
- return false;
- }
- //下面这个官网Example的Fun,读取已有菜单项列表时候,实现的IEnumerable,如果不需要,完全可以注释掉;不属于IContextMenuHandler接口规定的
- private static IEnumerable<Tuple<string, CefMenuCommand, bool>> GetMenuItems(IMenuModel model)
- {
- for (var i = 0; i < model.Count; i++)
- {
- var header = model.GetLabelAt(i);
- var commandId = model.GetCommandIdAt(i);
- var isEnabled = model.IsEnabledAt(i);
- yield return new Tuple<string, CefMenuCommand, bool>(header, commandId, isEnabled);
- }
- }
- }
- //在初始化ChromiumWebBrowser后,指定其MenuHandler 即可.
- browser1.MenuHandler = new MenuHandler();
关于代码,再啰嗦几点:
1.CefSharp右键菜单功能由IContextMenuHandler接口定义.
2.有的人看了官方的例子,可能会卡在webBrowser.Dispatcher.Invoke上面. winfrom中是没有Dispatcher的,Dispatcher只是调度器,在winform中直接使用Invoke调用即可,跟平时写的跨线程的UI访问需要使用委托来访问以确保线程安全一样.
3.官方的Example也是显示实现接口,文章代码尽量与翻译官方Example所以写的显示实现接口,实际上隐式实现接口是一样可用的.
4.官方Example中在 RunContextMenu 方法中写了一大串的代码,实现了完整的WPF菜单栏绘制,是对winform版本的开发者的主要误导之一。(实际上Example中有注释申明了使用内置的ContextMenu只需要返回false即可,是由于WPF中需要集成到现有的消息循环中才需要重绘)
所以遇到问题还是要多看官方的文档,因为转载者基本上把这段注释改掉了,如果你尝试在winform中在这里模仿wpf代码进行重绘,测了下可以成功,但是弹出速度极慢,重绘代码不发了,因为弹出速度感人毫无参考意义,winform即便是要重绘也应该是在OnBeforeContextMenu里面设定才对.
关于需要彻底禁用右键菜单,只要理解了上面的代码,就应该知道有很多很多处地方都可以实现,随便任意一处即可.
5. 右键菜单中的点击后的功能是什么,这些都是可以自己设定的.
右键菜单的功能的设定和可以实现的功能,不一定局限于浏览器基础功能的范畴,
也可以实现其它浏览器之外的其它任务和工作也是可以的,灵活运用即可.






广告位