How to hide the default context menu in the CefSharp Chromium browser in WPF

Using the CefSharp Chromium Web Browser in WPF / XAML


An example of not only how to use CefSharp.WinForms.ChromiumWebBrowser version 67 in a Visual Studio WPF application, but to hide the default context menu that show up on right-clicking the browser area.  See the following post for a general description of how to use CefSharp in Visual Studio:

Step 1: Create a new Visual Studio project

To start with create a new Visual Studio WPF application:

Step 2: Install the necessary libraries

Obtain CefSharp

Select Tool > NuGet Package manager > Package Manager Console.

Use the command:

PM> install-package CefSharp.Wpf

Now add the dll references.  Right-click on References, select ‘Add reference’

When the dialog appears, select the Browse button. Navigate to the ‘packages’ folder that NuGet has installed to your Visual Studio project. For this project I’m choosing the x86 version.

CefSharp.Wpf.dll

CefSharp.dll, CefSharp.Core.dll, CefSharp.BrowserSubprocessCore.dll:

Step 3: Update the Configuration Manager

In the Configuration Manager make sure your are set to either x86 or x64 – NOT ‘Any CPU’:

Step 4: Embed the CefSharp Chromium web browser control

Embed the web browser control, namely, a reference to the CefSharp.Wpf namespace and the ChromiumBrowserControl itself.

<Window x:Class="CefSharpContextMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CefSharpContextMenu"
        mc:Ignorable="d"
        xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        Title="MainWindow" 
        Height="350" Width="525">
    <Grid>
        <wpf:ChromiumWebBrowser
            x:Name="Browser"
            Address="http://www.google.co.uk" />
    </Grid>
</Window>

Re-build your project. You may have to close and re-open your MainWindow.xaml file to get it to update and display correctly. When run the browser control appears embedded in the WPF application and navigates to the web address pointed to by the ChromiumWebBrowser ‘Address’ property, as shown.

Notice that when you right click on the browser we get the default context menu appear as shown, which may or may not be desirable:

Step 5: Add the Menu handling class

MenuHandler.cs

using CefSharp;

namespace CefSharpContextMenu
{
   public class MenuHandler : IContextMenuHandler
   {
      public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
      {
         model.Clear();
      }

      public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
      {

         return false;
      }

      public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
      {

      }

      public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
      {
         return false;
      }
   }
}

Step 6: Create a Web Browser helper class that uses the DependencyProperty:

WebBrowserHelper.cs

using CefSharp.Wpf;
using System.Windows;

namespace CefSharpContextMenu
{
   public static class WebBrowserHelper
   {
      public static readonly DependencyProperty MenuHandlerProperty =
            DependencyProperty.RegisterAttached("MenuHandler", typeof(MenuHandler), typeof(WebBrowserHelper),
                new PropertyMetadata(OnMenuHandlerChanged));

      public static MenuHandler GetMenuHandler(DependencyObject dependencyObject)
      {
         return (MenuHandler)dependencyObject.GetValue(MenuHandlerProperty);
      }

      public static void SetMenuHandler(DependencyObject dependencyObject, MenuHandler body)
      {
         dependencyObject.SetValue(MenuHandlerProperty, body);
      }

      private static void OnMenuHandlerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
         var browser = d as ChromiumWebBrowser;
         if (browser == null) return;

         browser.MenuHandler = e.NewValue as MenuHandler;
      }
   }
}

Step 7: Create the MainWindow ViewModel class

MainWindowViewModel.cs

using CefSharp;
using CefSharp.Wpf;
using System.ComponentModel;

namespace CefSharpContextMenu
{
   public class MainWindowViewModel : INotifyPropertyChanged
   {
      private MenuHandler _menuHandler;

      public MainWindowViewModel()
      {
         _menuHandler = new MenuHandler();
      }

      public MenuHandler MenuHandler
      {
         get
         {
            return _menuHandler;
         }
         set
         {
            if (_menuHandler == value) return;
            _menuHandler = value;
            RaisePropertyChanged("MenuHandler");
         }
      }

      public event PropertyChangedEventHandler PropertyChanged;

      public void RaisePropertyChanged(string propertyName)
      {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
   }
}

Step 8: Use the Dependency Property in the MainWindow.xaml

MainWindow.xaml

<Window x:Class="CefSharpContextMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CefSharpContextMenu"
        mc:Ignorable="d"
        xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        Title="MainWindow" 
        Height="350" Width="525">

    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    
    <Grid>
        <wpf:ChromiumWebBrowser
            x:Name="Browser"
            local:WebBrowserHelper.MenuHandler="{Binding MenuHandler}"
            Address="http://www.google.co.uk" />
    </Grid>
</Window>

So that on running the program once again and right-clicking on the CefSharp browser area, the default context menu no longer appears: