Wait for a page to load with CefSharp

James D picture James D · Apr 18, 2017 · Viewed 20.6k times · Source

first and foremost I am a novice at C# and learning Cefsharp + javascript as I go so please attempt to comment any solution you feel are necessary, will save me asking stupid questions.

I'm attempting to wait until the page has finished loading with Cefsharp to execute my code, I have tried several solutions found on other stackoverflow questions / github but no go.

I thought the solution was "NavStateChanged" but I'm getting a C# error of: "ChromiumWebBrowser does not contain a definition for 'NavStateChanged'"

Could anyone point me in the right direction or throw me a snippet ? I'm not asking you to write the entire thing for me but I'm genuinely lost here, im learning C#, Cefsharp & javascript all at once and well... its overwhelming.

This is the code I found while looking for a solution online, it also matches a lot of the github references but doesn't seem to work :/

EventHandler<NavStateChangedEventArgs> handler = null;
handler = (sender, args) = > {

    //TODO : show a loading gif until the page load completes

    //Wait for while page to finish loading not just the first frame
    if (!args.IsLoading)
    {
        chromeBrowser.NavStateChanged -= handler;

        MessageBox.Show("The page has completed loading", "Load completed", 
                        MessageBoxButtons.OK);
        //TODO : once load complete show the actual page
    }

Answer

James D picture James D · Apr 18, 2017

For anyone else wondering the same thing I did: Yes they are outdated, thank you for the link amaitland!

https://github.com/cefsharp/CefSharp/wiki/General-Usage#handlers

These appear to be all 3 correct loading states which were relevant to me:

browser.RenderProcessMessageHandler = new RenderProcessMessageHandler();

public class RenderProcessMessageHandler : IRenderProcessMessageHandler
{
  // Wait for the underlying `Javascript Context` to be created, this is only called for the main frame.
  // If the page has no javascript, no context will be created.
  void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame)
  {
    const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";

    frame.ExecuteJavaScriptAsync(script);
  }
}

//Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening)
browser.LoadingStateChanged += (sender, args) =>
{
  //Wait for the Page to finish loading
  if (args.IsLoading == false)
  {
    browser.ExecuteJavaScriptAsync("alert('All Resources Have Loaded');");
  }
}

//Wait for the MainFrame to finish loading
browser.FrameLoadEnd += (sender, args) =>
{
  //Wait for the MainFrame to finish loading
  if(args.Frame.IsMain)
  {
    args.Frame.ExecuteJavaScriptAsync("alert('MainFrame finished loading');");
  }
};