Search code examples
wpfcefsharpchromium-embedded

Why do CefSharp custom context menu commands not work most of the time?


I implemented a custom context menu for CefSharp based on this example from the CefSharp github page, to get around the issue that events are fired in different threads which resulted in the context menu not closing when clicking outside.

I basically copy pasted it from the original source, just added a few more cases for the commands and it seemed to work at first. However the commands are executed only sometimes (most of the time not).

I added some Console.WriteLine() to the code to check what was going on and it seems that the execution of the command is sometimes canceled before it's finished.

I'm not sure if it is a bug in CefSharp or CEF, or if the example implementation is just incomplete. I tried to remove the menu.Closed handler, just as an experiment but it seem to make no difference.

I searched the internet but couldn't find a bug that matches the description so I guess it's me. Unfortunately I have a hard time wrapping my head around this. If someone could point me in the right direction, or point out the mistake, that would be nice.

My code so far is basically the same as this example but with all cases for the commands.

I created a simple test application that is nothing but a Window with the Browser but the issue persists, although it happens less frequent. The Visual Studio Project I created for testing can be downloaded here.

If you try to copy a paste a word a few times with the context menu, you should see that it only works about 70% of the time. I guess it happens less often as in my actual app because my actual application is a big monster compared to the test app, and therefore slower.

enter image description here

Cef is version 3.3396.1786
CefSharp.Wpf is version 67.0.0
OS: Win10 x64


Solution

  • The issue is not CefSharp or Chromium. The Example uses RelayCommand for the MenuItem commands which has a parameter keepTargetAlive. The parameter is set to false by default. Adding true as an argument solves it and the commands are always executed.

    Example:

    menu.Items.Add(new MenuItem
    {
        Header = item.Item1.Replace("&", "_"),
        IsEnabled = item.Item3,
        Command = new RelayCommand(() =>
        {
            map_browser_functions(browser, parameters, item);
        }, keepTargetAlive: true)
    });