• CefSharp For WPF自定义右键菜单栏


    初始化

    <!--浏览器-->
    <cefSharpWPF:ChromiumWebBrowser Name="webBrowser" 
                                    Grid.Row="0" >
    </cefSharpWPF:ChromiumWebBrowser>
    
    public MainWindow()
    {
        InitializeComponent();
    
        //右键菜单栏
        MenuHandler.mainWindow = this;
        webBrowser.MenuHandler = new MenuHandler();
    }
    

    MenuHandler.cs

    public class MenuHandler : IContextMenuHandler
    {
        public static Window mainWindow { get; set; }
        void IContextMenuHandler.OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
        {
    
        }
    
        bool IContextMenuHandler.OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
        {
            return true;
        }
    
        void IContextMenuHandler.OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
        {
            //隐藏菜单栏
            var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
    
            chromiumWebBrowser.Dispatcher.Invoke(() =>
            {
                chromiumWebBrowser.ContextMenu = null;
            });
        }
    
        bool IContextMenuHandler.RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
        {
    
            //绘制了一遍菜单栏  所以初始化的时候不必绘制菜单栏,再此处绘制即可
            var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
    
            chromiumWebBrowser.Dispatcher.Invoke(() =>
            {
                var menu = new ContextMenu
                {
                    IsOpen = true
                };
    
                RoutedEventHandler handler = null;
    
                handler = (s, e) =>
                {
                    menu.Closed -= handler;
    
                    //If the callback has been disposed then it's already been executed
                    //so don't call Cancel
                    if (!callback.IsDisposed)
                    {
                        callback.Cancel();
                    }
                };
    
                menu.Closed += handler;
    
                menu.Items.Add(new MenuItem
                {
                    Header = "最小化",
                    Command = new CustomCommand(MinWindow)
                });
                menu.Items.Add(new MenuItem
                {
                    Header = "关闭",
                    Command = new CustomCommand(CloseWindow)
                });
                chromiumWebBrowser.ContextMenu = menu;
    
            });
    
            return true;
        }
    
        /// <summary>
        /// 关闭窗体
        /// </summary>
        private void CloseWindow()
        {
            //调用线程无法访问此对象,因为另一个线程拥有该对象
            //handler和window是两个线程,WPF做了线程安全。。。so以下
            mainWindow.Dispatcher.Invoke(
                new Action(
                        delegate
                        {
                            Application.Current.Shutdown();
                        }
                    ));
        }
    
        /// <summary>
        /// 最小化窗体
        /// </summary>
        private void MinWindow()
        {
            mainWindow.Dispatcher.Invoke(
                new Action(
                        delegate
                        {
                            mainWindow.WindowState = WindowState.Minimized;
                        }
                    ));
        }
    
        private static IEnumerable<Tuple<string, CefMenuCommand>> GetMenuItems(IMenuModel model)
        {
            var list = new List<Tuple<string, CefMenuCommand>>();
            for (var i = 0; i < model.Count; i++)
            {
                var header = model.GetLabelAt(i);
                var commandId = model.GetCommandIdAt(i);
                list.Add(new Tuple<string, CefMenuCommand>(header, commandId));
            }
    
            return list;
        }
    }
    

    CustomCommand.cs

    public class CustomCommand : ICommand
    {
        Action _TargetExecuteMethod;
        Func<bool> _TargetCanExecuteMethod;
        public event EventHandler CanExecuteChanged = delegate { };
    
        public CustomCommand(Action executeMethod)
        {
            _TargetExecuteMethod = executeMethod;
        }
    
        bool ICommand.CanExecute(object parameter)
        {
            if (_TargetCanExecuteMethod != null)
            {
                return _TargetCanExecuteMethod();
            }
            if (_TargetExecuteMethod != null)
            {
                return true;
            }
            return false;
        }
    
        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    
        void ICommand.Execute(object parameter)
        {
            _TargetExecuteMethod?.Invoke();
        }
    }
    

    参考资料

    https://github.com/cefsharp/CefSharp/issues/1795

  • 相关阅读:
    MyEclipse:详细使用教程
    JDK安装与配置详细图文教程
    windows下python3.6版本安装pygame
    windows下如何下载并安装Python
    python的 del 函数是删对象还是删引用
    python strip()函数的用法
    python的垃圾回收机制
    python中的sort方法
    python中del函数的垃圾回收
    两个数交换
  • 原文地址:https://www.cnblogs.com/Lulus/p/7998214.html
Copyright © 2020-2023  润新知