Muokkaa

Jaa


Customize context menus in WebView2

The WebView2 control provides a default context menu, and you can create your own context menu when using a WebView2 control. Use the ContextMenuRequested API to customize the context-menus (right-click menus) of a WebView2 app. For example, you can do any of the following:

  • Add a custom context menu.

    Instead of using the default context menu, your host app can draw its own context menu by using the information that's sent from the WebView2 context menu. Your app handles the ContextMenuRequested event. You can use the data provided in the Event arguments of ContextMenuRequested to display a custom context menu with entries of your choice. For this case, you handle the event and request a deferral.

    You can add default menu items and/or custom menu items to a custom context menu.

  • Add default menu items to a custom context menu.

  • Add custom menu items to a default context menu.

  • Remove default or custom menu items from the default context menu.

  • Disable context menus.

Terminology:

Term Definition
menu item A broad term. Includes checkbox, command, radio button, separator, and submenu.
command A narrow term. One of five types of menu item.
context menu Either a default context menu (right-click menu) belonging to the WebView2 control, or a custom context menu (right-click menu) belonging to your host app.

Adding a custom context menu

Instead of using the default context menu, your host app can draw its own context menu by using the information that's sent from the WebView2 context menu. Your app handles the ContextMenuRequested event. You can use the data provided in the Event arguments of ContextMenuRequested to display a custom context menu with entries of your choice. For this case, you handle the event and request a deferral.

When the user selects a command from your custom context menu, your app needs to tell the WebView2 control which command the user selected, by using the SelectedCommandId property.

You can add default menu items and/or custom menu items to a custom context menu.

To display a custom context menu that contains your desired menu items, use the data provided in the CoreWebView2ContextMenuRequestedEventArgs of the CoreWebView2 ContextMenuRequested Event. For this case, you specify Handled to be true, and request a deferral.

On a CoreWebView2.ContextMenuRequested event, add an event listener that has a CoreWebView2ContextMenuRequestedEventArgs.

The MenuItems property of CoreWebView2ContextMenuRequestedEventArgs provides the tree of the WebView2's context menu items for the right-clicked context. To include WebView2 context menu items in your app's context menu, iterate through the IList<CoreWebView2ContextMenuItem>, adding a CoreWebView2ContextMenuItem for each menu item. Test the .Kind of each menu item, such as Command or Separator.

Example: Adding a custom context menu

The following sample presents the WebView2 context menu in the Win32/WPF context menu format.

webView.CoreWebView2.ContextMenuRequested += delegate (object sender, 
                                    CoreWebView2ContextMenuRequestedEventArgs args)
{
    IList<CoreWebView2ContextMenuItem> menuList = args.MenuItems;
    CoreWebView2Deferral deferral = args.GetDeferral();
    args.Handled = true;
    ContextMenu cm = new ContextMenu();
    cm.Closed += (s, ex) => deferral.Complete();
    PopulateContextMenu(args, menuList, cm);
    cm.IsOpen = true;
};
void PopulateContextMenu(CoreWebView2ContextMenuRequestedEventArgs args, 
IList<CoreWebView2ContextMenuItem> menuList, ItemsControl cm)
{
    for (int i = 0; i < menuList.Count; i++)
    {
        CoreWebView2ContextMenuItem current = menuList[i];
        if (current.Kind == CoreWebView2ContextMenuItemKind.Separator)
        {
            Separator sep = new Separator();
            cm.Items.Add(sep);
            continue;
        }
        MenuItem newItem = new MenuItem();
        // The accessibility key is the key after the & in the label
        // Replace with '_' so it is underlined in the label
        newItem.Header = current.Label.Replace('&', '_');
        newItem.InputGestureText = current.ShortcutKeyDescription;
        newItem.IsEnabled = current.IsEnabled;
        if (current.Kind == CoreWebView2ContextMenuItemKind.Submenu)
        {
            PopulateContextMenu(args, current.Children, newItem);
        }
        else
        {
            if (current.Kind == CoreWebView2ContextMenuItemKind.CheckBox
            || current.Kind == CoreWebView2ContextMenuItemKind.Radio)
            {
                newItem.IsCheckable = true;
                newItem.IsChecked = current.IsChecked;
            }

            newItem.Click += (s, ex) =>
            {
                args.SelectedCommandId = current.CommandId;
            };
        }
        cm.Items.Add(newItem);
    }
}

Adding menu items to a context menu

You can:

  • Add default menu items to a custom context menu, as shown above in "Adding a custom context menu".

  • Add custom menu items to a default context menu, as shown below in "Adding custom menu items to a default context menu".

Adding custom menu items to a default context menu

To add custom menu items to the default context menu, use the following API items.

Example: Adding custom menu items to a default context menu

The following example adds a Display Page Uri command to the WebView2 context menu.

webView.CoreWebView2.ContextMenuRequested += delegate (object sender, 
                                    CoreWebView2ContextMenuRequestedEventArgs args)
{
    // add new item to end of collection
    CoreWebView2ContextMenuItem newItem = 
                        webView.CoreWebView2.Environment.CreateContextMenuItem(
        "Display Page Uri", null, CoreWebView2ContextMenuItemKind.Command);
        newItem.CustomItemSelected += delegate (object send, Object ex)
        {
            string pageUri = args.ContextMenuTarget.PageUri;
            System.Threading.SynchronizationContext.Current.Post((_) =>
            {
                MessageBox.Show(pageUri, "Page Uri", MessageBoxButton.OK);
            }, null);
        };
    menuList.Insert(menuList.Count, newItem);
};

Removing menu items from a default context menu

You can remove default or custom menu items from the default context menu.

Example: Removing menu items from a default context menu

The following example removes the Save image as command from the WebView2 context menu.

webView.CoreWebView2.ContextMenuRequested += delegate (object sender, 
                                    CoreWebView2ContextMenuRequestedEventArgs args)
{
    IList<CoreWebView2ContextMenuItem> menuList = args.MenuItems;
    CoreWebView2ContextMenuTargetKind context = args.ContextMenuTarget.Kind;
    if (context == CoreWebView2ContextMenuTargetKind.Image)
    {
        for (int index = 0; index < menuList.Count; index++)
        {
            if (menuList[index].Name == "saveImageAs")
            {
                menuList.RemoveAt(index);
                break;
            }
        }
    }
};

Detecting when the user requests a context menu

This section explains how to detect when the user requests opening a context menu. It's the same for custom or default context menus.

When a user requests opening a context menu (such as by right-clicking), your app needs to listen for the ContextMenuRequested event.

When your app detects this event, your app should do some combination of the following:

  • Add custom menu items to the default context menu.
  • Remove custom menu items from the default context menu.
  • Open a custom context menu.

The ContextMenuRequested event indicates that the user requested opening a context menu.

The WebView2 control raises this event to indicate that the user requested opening a context menu in the WebView2 control, such as by right-clicking.

The WebView2 control only raises the ContextMenuRequested event if the current webpage allows the context menu to appear; that is, if the AreDefaultContextMenusEnabled property is true.

The CoreWebView2ContextMenuRequestedEventArgs contains the following information:

  • An ordered list of ContextMenuItem objects to populate the custom context menu. The ordered list includes the following:

    • The internal name of the menu item.
    • The UI label of the menu item, displayed to the user in the UI.
    • The kind of menu item.
    • A keyboard shortcut Description, if any, such as Alt+C.
    • Any other properties of the custom menu item.
  • The coordinates where the context menu was requested, so your app can detect which UI item the user right-clicked. The coordinates are defined in relation to the upper left corner of the WebView2 control.

  • A selection object that will include the kind of context selected and the appropriate context menu parameter data.

When the user selects a custom menu item on a context menu, the WebView2 control fires a CustomItemSelected event.

When your host app indicates to WebView2 that a user selected a menu item on a context menu, WebView2 then runs the selected command.

Detecting when the user selects a custom menu item

Your host app can handle the user-selected menu item, or your app can return the menu item to the WebView2 control to handle the user-selected menu item.

Your host app should listen for the CustomItemSelected event, which is raised when the user selects a custom menu item on a default or custom context menu.

The WebView2 control raises this event to indicate that the user selected a custom menu item that your app added to a context menu.

If the user selects a custom menu item, the CustomMenuItemSelected event is raised on the context menu item object that was selected, in these cases:

  • The app adds custom menu items, but defers the context menu UI to the WebView2 platform.

  • The app adds custom menu items, shows custom UI, and sets the SelectedCommandId property to the ID of the custom menu item.

Reporting a selected command menu item to WebView2

When the user selects a WebView2 context menu command (a default menu item that's in a custom context menu), the host app can optionally report that selection to WebView2 so that WebView2 will invoke the command.

Custom menu items

If your host app reports a custom menu item as the selected menu item, then the CustomMenuItemSelected event will be fired for the custom menu item.

Disabling context menus

The AreDefaultContextMenusEnabled property controls whether any context menu can be opened. If the WebView2 AreDefaultContextMenusEnabled setting is set to False, that disables context menus, and the ContextMenuRequested event won't be raised, such as when the user right-clicks.

API Reference overview

See also