Kontextmenüs für eine BlazorWebView aktivieren

Problembeschreibung

In meiner Desktop-Anwendung mit Windows Forms ist eine BlazorWebView enthalten, die auf WebView2 (also Chromium) basiert.

Darin instanziiere ich dann diverse Blazor-Komponenten.

Dort hatte ich das Problem, dass das normale Browser-Kontextmenü nicht erschienen ist, wenn der Benutzer rechts auf Elemente geklickt hat. Weder auf ein HTML-Element, noch auf ein Eingabe-Textfeld.

Und das, obwohl ich beim Initialisieren der BlazorWebView eigentlich alles korrekt eingestellt hatte:

WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
WebView.CoreWebView2.ContextMenuRequested += (s2, e2) => { /*...*/ };

Trotzdem war es so, als hätte ich die Einstellungen gar nicht vorgenommen.

Lösung

Was mich dann der Lösung näher gebracht hat, war die ZIP-Datei mit einem Beispielprojekt in diesem GitHub-Issue-Kommentar.

Im Endeffekt war die Lösung trivial, wie so oft:

Anstatt obigen Code im CoreWebView2InitializationCompleted-Ereignishandler zu binden, habe ich den Code im (später aufgerufenen) BlazorWebViewInitialized-Ereignishandler aufgerufen.

Anschließend hat sich das ganze korrekt verhalten.

Mein Beispiel-Form:

public MainForm()
{
	InitializeComponent();

	// "CoreWebView2InitializationCompleted" wird VOR "BlazorWebViewInitialized" aufgerufen.
	blazorWebView.WebView.CoreWebView2InitializationCompleted += (s, a) =>
	{
		if (!a.IsSuccess) return; // Beim 1. Aufruf.

		var e = (WebView2?)s;

		e!.CoreWebView2.Settings.AreDevToolsEnabled = true;
		e.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
		e.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = true;

		blazorWebView.WebView.KeyDown += (s2, e2) =>
		{
			if (e2.KeyCode == Keys.F12 &&
				blazorWebView.WebView.CoreWebView2 != null)
			{
				blazorWebView.WebView.CoreWebView2.OpenDevToolsWindow();
				e2.Handled = true;
			}
		};
	};

	// "BlazorWebViewInitialized" wird NACH "CoreWebView2InitializationCompleted" aufgerufen.
	// Die Einstellungen greifen erst hier, nicht, wenn sie im "CoreWebView2InitializationCompleted"-Event
	// gesetzt werden. 
	blazorWebView.BlazorWebViewInitialized += (_, e) =>
	{
		e.WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
		e.WebView.CoreWebView2.ContextMenuRequested += (s2, e2) => { };
	};

	// --

	blazorWebView.HostPage = @"wwwroot/index.html";
	blazorWebView.Services = Program.ServiceProvider!;
	blazorWebView.RootComponents.Add<Start>(@"#app");
}

Dieser Thread auf Reddit dazu war auch hilfreich, ebenso wie dieses GitHub-Issue dazu.