Context Menu in WPF App

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Context Menu in WPF App

Postby comanighttrain » Wed Jan 28, 2015 5:18 am

Hi Folks,

Please excuse my inexperience - I've been given a project in work which is already written and I need to do some work on it. I have no experience of CEF until now...

The latest version of CEF includes the spell checker. I need to get that working but the context menu is not appearing - Google seems to indicate that most people struggle to disable it rather than enable it which makes me think it should be enabled by default?

Is there any documentation on the context menu handling I can look at?

Thanks
comanighttrain
Newbie
 
Posts: 8
Joined: Wed Jan 28, 2015 5:05 am

Re: Context Menu in WPF App

Postby comanighttrain » Wed Jan 28, 2015 11:18 am

Thanks for approving my post :D

I should report that since my original post I've added the context menu:

Code: Select all
WebView = new ChromiumWebBrowser();
WebView.Address = Properties.Settings.Default.Url;
WebView.BrowserSettings = browserSettings;
WebView.ContextMenu = new System.Windows.Controls.ContextMenu();
WebView.ContextMenu.Items.Add(new MenuItem() { Header = "Back", Command = WebView.BackCommand }); 


And it does appear. Now I need to implement the spell checker but as far as I can find on google again this hasn't been discussed.

I'm thinking I need to catch the context menu before it's rendered and add the corrected spelling options. Following that when one is clicked I need an event which will replace the invalid word with the corrected one...

any pointers?
comanighttrain
Newbie
 
Posts: 8
Joined: Wed Jan 28, 2015 5:05 am

Re: Context Menu in WPF App

Postby magreenblatt » Wed Jan 28, 2015 1:21 pm

I don't know how WPF works, but in C/C++ the context menu is built by CEF internally and passed to the client via the CefMenuModel argument of CefContextMenuHandler::OnBeforeContextMenu. If you build the menu yourself look at the CefContextMenuParams argument which returns the suggestions via GetDictionarySuggestions. When a suggestion is selected call CefBrowserHost::ReplaceMisspelling.
magreenblatt
Site Admin
 
Posts: 12408
Joined: Fri May 29, 2009 6:57 pm

Re: Context Menu in WPF App

Postby comanighttrain » Thu Jan 29, 2015 7:26 am

magreenblatt wrote:I don't know how WPF works, but in C/C++ the context menu is built by CEF internally and passed to the client via the CefMenuModel argument of CefContextMenuHandler::OnBeforeContextMenu. If you build the menu yourself look at the CefContextMenuParams argument which returns the suggestions via GetDictionarySuggestions. When a suggestion is selected call CefBrowserHost::ReplaceMisspelling.


Thanks for the reply magreen

I was trying to follow the same line of thinking with the C# code as you posted regarding c/c++ BUT the ContextMenu member of the ChromiumWebBrowser isn't a Cef class - instead it seems to be a normal ContextMenu Framework Element class.

I did find an interface in CefSharp.IContextMenuParams with the methods you'd expect from the context menu items. I just can't see how it all hangs together yet.
comanighttrain
Newbie
 
Posts: 8
Joined: Wed Jan 28, 2015 5:05 am

Re: Context Menu in WPF App

Postby comanighttrain » Fri Jan 30, 2015 12:14 pm

Made some more progress today - I can get spelling mistakes to be corrected but I have a race condition that I cannot eliminate...

Menu Handler

Code: Select all
internal class MenuHandler : IMenuHandler
    {
        public List<String> CorrectionSuggestions = new List<string>();

        public bool OnBeforeContextMenu(IWebBrowser browser)
        {
            // Return false if you want to disable the context menu.
            return true;
        }

        public bool OnBeforeContextMenu(IWebBrowser browser, IContextMenuParams parameters)
        {
            CorrectionSuggestions = new List<string>();

            foreach (string correction in parameters.DictionarySuggestions)
            {
                CorrectionSuggestions.Add(correction);
            }

            return true;
        }


Code

Code: Select all
 void ContextMenu_Opened(object sender, System.Windows.RoutedEventArgs e)
        {
            System.Threading.Thread.Sleep(5000);
            MenuHandler handler = WebView.MenuHandler as MenuHandler;

           WebView.ContextMenu = new ContextMenu();

            foreach (string s in handler.CorrectionSuggestions)
            {
                MenuItem newMenuItem = new MenuItem();
                List<object> browserAndMenuItem = new List<object>();
                browserAndMenuItem.Add(WebView);
                browserAndMenuItem.Add(newMenuItem);
                newMenuItem.Header = s;
                newMenuItem.CommandParameter = browserAndMenuItem; //try list of objects
                newMenuItem.Command = new testCommand();
                WebView.ContextMenu.Items.Add(newMenuItem);
            }
        }

public class testCommand : ICommand
    {
        public delegate void EventHandler(object sender, ProgressEventArgs e);
        public event System.EventHandler CanExecuteChanged;

        public void Execute(object o)
        {
            List<object> browserAndMenuItem = new List<object>();
            browserAndMenuItem = o as List<object>;
            ChromiumWebBrowser browser = browserAndMenuItem[0] as ChromiumWebBrowser;
            MenuItem menuItem = browserAndMenuItem[1] as MenuItem;
            browser.ReplaceMisspelling(menuItem.Header.ToString());
        }

        public bool CanExecute(object o)
        {
            return true;
        }
    }
Last edited by comanighttrain on Mon Feb 09, 2015 7:10 am, edited 1 time in total.
comanighttrain
Newbie
 
Posts: 8
Joined: Wed Jan 28, 2015 5:05 am

Re: Context Menu in WPF App

Postby comanighttrain » Mon Feb 09, 2015 7:09 am

We managed to get our spell check working with the following code:

We added a dispatcher:

Code: Select all
void kMenuHandler_SuggestionsPopulated(object sender, EventArgs e)
        {
            // This isn't run from the UI thread so need to use Dispatcher.
            Dispatcher.Invoke(() =>
            {
                MenuHandler handler = WebView.MenuHandler as MenuHandler;
                WebView.ContextMenu.Items.Clear();

                foreach (string s in handler.CorrectionSuggestions)
                {
                    MenuItem newMenuItem = new MenuItem();
                    List<object> browserAndMenuItem = new List<object>();
                    browserAndMenuItem.Add(WebView);
                    browserAndMenuItem.Add(newMenuItem);
                    newMenuItem.Header = s;
                    newMenuItem.CommandParameter = browserAndMenuItem; //try list of objects
                    newMenuItem.Command = new SpellCheckCommand();
                    WebView.ContextMenu.Items.Add(newMenuItem);
                }

                WebView.ContextMenu.IsOpen = true;
            });
        }


And a wait on the command

Code: Select all
public class SpellCheckCommand : ICommand
    {
        public delegate void EventHandler(object sender, ProgressEventArgs e);
        public event System.EventHandler CanExecuteChanged;

        public void Execute(object o)
        {
            try
            {
                // Need this here for some reason.
                Thread.Sleep(100);
            }
            catch (Exception) { }

            List<object> browserAndMenuItem = new List<object>();
            browserAndMenuItem = o as List<object>;
            ChromiumWebBrowser browser = browserAndMenuItem[0] as ChromiumWebBrowser;
            MenuItem menuItem = browserAndMenuItem[1] as MenuItem;
            browser.ReplaceMisspelling(menuItem.Header.ToString());
        }

        public bool CanExecute(object o)
        {
            return true;
        }
    }
comanighttrain
Newbie
 
Posts: 8
Joined: Wed Jan 28, 2015 5:05 am

Re: Context Menu in WPF App

Postby angshuman » Thu Jan 17, 2019 6:18 am

Hi,
I enabled the spell check service which causes the red underlines below the wrongly spelled word (in WPF version).

Code: Select all
private static void IsBrowserInitializedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Cef.UIThreadTaskFactory.StartNew(() =>
            {
                var cefBrowser = (BrowserControl)d;
                var browserRequestContext = cefBrowser.GetBrowserHost().RequestContext;

                string error = string.Empty;
                if(!browserRequestContext.SetPreference("browser.enable_spellchecking", true, out error))
                {
                    _log.Error($"Failed to enable spell check on the browser. Error is {error}");
                }
            });
        }



But, when I right click and put a breakpoint in my ContextMenu handler, the parameters IsSpellCheckEnabled and DictionarySuggestions of IContextMenuParams are false and empty respectively. Is there something extra I need to do to enable that ?
angshuman
Techie
 
Posts: 10
Joined: Thu Jan 17, 2019 6:12 am


Return to Support Forum

Who is online

Users browsing this forum: Majestic-12 [Bot] and 24 guests