🗂

Blazor Hybrid でテキストボックスの右クリックメニューを表示する

2024/01/07に公開

Windows 版の Blazor Hybrid では、テキストボックスの右クリックメニューが表示されません。地味にコピペが出来ないので不便です。
この解決方法は、1つ前の記事にある BlazorHybridInitialized イベントで AreDefaultContextMenusEnabledtrue に設定して ContextMenuRequested イベントでコンテキストメニューからブラウザ固有のメニューを削除することで実現可能です。

この方法は、以下の Issue で紹介されている方法です。

https://github.com/dotnet/maui/issues/11398

具体的なコードは、上記の Issue から行ける Pull Request に記載されています。

https://github.com/musictopia2/NoRightClickOnInputsOrTextAreaSample/pull/1

上記の PR から該当部分のコードだけを抜粋します。

<!-- BlazorWebViewInitialized イベントハンドラを登録 -->
<blazor:BlazorWebView
    x:Name="blazorWebView"
    BlazorWebViewInitialized="BlazorWebViewInitialized"
    HostPage="wwwroot/index.html"
    Services="{x:Static local:App.ServiceProvider}">
    <blazor:BlazorWebView.RootComponents>
        <blazor:RootComponent ComponentType="{x:Type local:Routes}" Selector="#app" />
    </blazor:BlazorWebView.RootComponents>
</blazor:BlazorWebView>
private void BlazorWebViewInitialized(object sender, BlazorWebViewInitializedEventArgs e)
{
    // コンテキストメニューを有効化
    e.WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
    e.WebView.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested;
}

private void CoreWebView2_ContextMenuRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuRequestedEventArgs e)
{
    Debug.WriteLine($"IsEditable? {e.ContextMenuTarget.IsEditable}");

    // 編集可能な項目の場合には、不要なメニューを削除する
    if (e.ContextMenuTarget.IsEditable)
    {
        // For editable elements such as <input> and <textarea> we enable the context menu but remove items we don't want in this app
        var itemNamesToRemove = new[] { "share", "webSelect", "webCapture", "inspectElement" };
        var menuIndexesToRemove =
            e.MenuItems
                .Select((m, i) => (m, i))
                .Where(m => itemNamesToRemove.Contains(m.m.Name))
                .Select(m => m.i)
                .Reverse();

        Debug.WriteLine($"Removing these indexes: {string.Join(", ", menuIndexesToRemove.Select(i => i.ToString()))}");
        foreach (var menuIndexToRemove in menuIndexesToRemove)
        {
            Debug.WriteLine($"Removing {e.MenuItems[menuIndexToRemove].Name}...");
            e.MenuItems.RemoveAt(menuIndexToRemove);
        }

        // Trim extra separators from the end
        while (e.MenuItems.Last().Kind == Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuItemKind.Separator)
        {
            e.MenuItems.RemoveAt(e.MenuItems.Count - 1);
        }
    }
    else
    {
        // For non-editable elements such as <div> we disable the context menu
        e.Handled = true;
    }
}

こうすることで、以下のような右クリックメニューが表示されるようになります。

Microsoft (有志)

Discussion