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

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

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

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

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

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

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

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

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

用語:

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

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

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

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

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

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

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

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

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

次の例では、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 コントロールは、現在の ContextMenuRequested Web ページでコンテキスト メニューの表示が許可されている場合にのみイベントを発生させます。つまり、 プロパティが AreDefaultContextMenusEnabled の場合は trueです。

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 リファレンスの概要

関連項目