WebView2 でコンテキスト メニューをカスタマイズする

WebView2 コントロールには既定のコンテキスト メニューが用意されており、WebView2 コントロールを使用するときに独自のコンテキスト メニューを作成できます。 ContextMenuRequested API を使用して、WebView2 アプリのコンテキスト メニュー (右クリック メニュー) をカスタマイズします。 たとえば、次のいずれかの操作を実行できます。

  • カスタム コンテキスト メニューを追加します。

    既定のコンテキスト メニューを使用する代わりに、ホスト アプリは WebView2 コンテキスト メニューから送信される情報を使用して、独自のコンテキスト メニューを描画できます。 アプリが ContextMenuRequested イベントを処理します。 ContextMenuRequestedの Event 引数で指定されたデータを使用して、任意のエントリを含むカスタム コンテキスト メニューを表示できます。 この場合、イベントを処理し、遅延を要求します。

    既定のメニュー項目やカスタム メニュー項目をカスタム コンテキスト メニューに追加できます。

  • カスタム コンテキスト メニューに既定のメニュー項目を追加します。

  • カスタム メニュー項目を既定のコンテキスト メニューに追加します。

  • 既定のコンテキスト メニューから既定またはカスタム メニュー項目を削除します。

  • コンテキスト メニューを無効にします。

用語:

用語 定義
メニュー項目 広範な用語。 チェック ボックス、コマンド、ラジオ ボタン、区切り記号、サブメニューが含まれます。
命令 狭い用語。 5 種類のメニュー項目のいずれか。
コンテキスト メニュー WebView2 コントロールに属する既定のコンテキスト メニュー (右クリック メニュー) またはホスト アプリに属するカスタム コンテキスト メニュー (右クリック メニュー) のいずれか。

カスタム コンテキスト メニューの追加

既定のコンテキスト メニューを使用する代わりに、ホスト アプリは WebView2 コンテキスト メニューから送信される情報を使用して、独自のコンテキスト メニューを描画できます。 アプリが ContextMenuRequested イベントを処理します。 ContextMenuRequestedの Event 引数で指定されたデータを使用して、任意のエントリを含むカスタム コンテキスト メニューを表示できます。 この場合、イベントを処理し、遅延を要求します。

ユーザーがカスタム コンテキスト メニューからコマンドを選択すると、 SelectedCommandId プロパティを使用して、ユーザーが選択したコマンドを WebView2 コントロールに伝える必要があります。

既定のメニュー項目やカスタム メニュー項目をカスタム コンテキスト メニューに追加できます。

目的のメニュー項目を含むカスタム コンテキスト メニューを表示するには、CoreWebView2ContextMenuRequested イベントCoreWebView2ContextMenuRequestedEventArgsで提供されるデータを使用します。 この場合は、trueするHandledを指定し、遅延を要求します。

CoreWebView2.ContextMenuRequested イベントで、CoreWebView2ContextMenuRequestedEventArgsを持つイベント リスナーを追加します。

CoreWebView2ContextMenuRequestedEventArgsMenuItems プロパティは、右クリックしたコンテキストの WebView2 のコンテキスト メニュー項目のツリーを提供します。 WebView2 コンテキスト メニュー項目をアプリのコンテキスト メニューに含めるには、 IList<CoreWebView2ContextMenuItem>を反復処理し、メニュー項目ごとに CoreWebView2ContextMenuItem を追加します。 CommandSeparatorなど、各メニュー項目の.Kindをテストします。

例: カスタム コンテキスト メニューの追加

次の例では、Win32/WPF コンテキスト メニュー形式の WebView2 コンテキスト メニューを示します。

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);
    }
}

コンテキスト メニューへのメニュー項目の追加

次の操作を行うことができます:

  • 上記の「カスタム コンテキスト メニューの追加」に示すように、既定のメニュー項目をカスタム コンテキスト メニューに追加します。

  • 「既定のコンテキスト メニューにカスタム メニュー項目を追加する」で示すように、カスタム メニュー項目を既定のコンテキスト メニューに追加します。

既定のコンテキスト メニューへのカスタム メニュー項目の追加

カスタム メニュー項目を既定のコンテキスト メニューに追加するには、次の API 項目を使用します。

例: カスタム メニュー項目を既定のコンテキスト メニューに追加する

次の例では、WebView2 コンテキスト メニューに Display Page Uri コマンドを追加します。

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);
};

既定のコンテキスト メニューからメニュー項目を削除する

既定のコンテキスト メニューから既定またはカスタム メニュー項目を削除できます。

例: 既定のコンテキスト メニューからメニュー項目を削除する

次の例では、WebView2 コンテキスト メニューから [イメージとして保存 ] コマンドを削除します。

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;
            }
        }
    }
};

ユーザーがコンテキスト メニューを要求するタイミングの検出

このセクションでは、ユーザーがコンテキスト メニューの開きを要求するタイミングを検出する方法について説明します。 カスタム コンテキスト メニューまたは既定のコンテキスト メニューでも同じです。

ユーザーがコンテキスト メニュー (右クリックなど) を開くよう要求した場合、アプリは ContextMenuRequested イベントをリッスンする必要があります。

アプリでこのイベントが検出されると、アプリは次の組み合わせを実行する必要があります。

  • カスタム メニュー項目を既定のコンテキスト メニューに追加します。
  • 既定のコンテキスト メニューからカスタム メニュー項目を削除します。
  • カスタム コンテキスト メニューを開きます。

ContextMenuRequested イベントは、ユーザーがコンテキスト メニューの開きを要求したことを示します。

WebView2 コントロールは、このイベントを発生させ、ユーザーが WebView2 コントロールでコンテキスト メニューを開くよう要求したことを示します (右クリックなど)。

WebView2 コントロールでは、現在の Web ページでコンテキスト メニューの表示が許可されている場合、つまり、AreDefaultContextMenusEnabled プロパティがtrueされている場合にのみ、ContextMenuRequested イベントが発生します。

CoreWebView2ContextMenuRequestedEventArgs には、次の情報が含まれています。

  • カスタム コンテキスト メニューを設定する ContextMenuItem オブジェクトの順序付きリスト。 順序付きリストには、次のものが含まれます。

    • メニュー項目の内部名。
    • UI でユーザーに表示されるメニュー項目の UI ラベル。
    • メニュー項目の種類。
    • Alt + C など、キーボード ショートカットの [説明] (存在する場合)。
    • カスタム メニュー項目のその他のプロパティ。
  • コンテキスト メニューが要求された座標。これにより、アプリはユーザーが右クリックした UI 項目を検出できます。 座標は、WebView2 コントロールの左上隅に対して定義されます。

  • 選択したコンテキストの種類 適切なコンテキスト メニュー パラメーター データを含む selection オブジェクト。

ユーザーがコンテキスト メニューでカスタム メニュー項目を選択すると、WebView2 コントロールによって CustomItemSelected イベントが発生します。

ホスト アプリが WebView2 に対して、ユーザーがコンテキスト メニューのメニュー項目を選択したことを示すと、WebView2 は選択したコマンドを実行します。

ユーザーがカスタム メニュー項目を選択した場合の検出

ホスト アプリは、ユーザーが選択したメニュー項目を処理することも、アプリから WebView2 コントロールにメニュー項目を返して、ユーザーが選択したメニュー項目を処理することもできます。

ホスト アプリは、 CustomItemSelected イベントをリッスンする必要があります。これは、ユーザーが既定のコンテキスト メニューまたはカスタム コンテキスト メニューでカスタム メニュー項目を選択したときに発生します。

WebView2 コントロールは、アプリがコンテキスト メニューに追加したカスタム メニュー項目をユーザーが選択したことを示すために、このイベントを発生させます。

ユーザーがカスタム メニュー項目を選択した場合、選択したコンテキスト メニュー項目オブジェクトで CustomMenuItemSelected イベントが発生します。このような場合は、次のようになります。

  • アプリはカスタム メニュー項目を追加しますが、コンテキスト メニュー UI を WebView2 プラットフォームに延期します。

  • アプリは、カスタム メニュー項目を追加し、カスタム UI を表示し、 SelectedCommandId プロパティをカスタム メニュー項目の ID に設定します。

選択したコマンド メニュー項目を WebView2 に報告する

ユーザーが WebView2 コンテキスト メニュー コマンド (カスタム コンテキスト メニュー内の既定のメニュー項目) を選択すると、ホスト アプリはオプションでその選択内容を WebView2 に報告して、WebView2 がコマンドを呼び出すようにすることができます。

カスタム メニュー項目

ホスト アプリが選択したメニュー項目としてカスタム メニュー項目を報告する場合、カスタム メニュー項目に対して CustomMenuItemSelected イベントが発生します。

コンテキスト メニューの無効化

AreDefaultContextMenusEnabled プロパティは、コンテキスト メニューを開くことができるかどうかを制御します。 WebView2 AreDefaultContextMenusEnabled 設定が False に設定されている場合、コンテキスト メニューが無効になり、ユーザーが右クリックしたときなど、 ContextMenuRequested イベントは発生しません。

API リファレンスの概要

関連項目