Wait for a page to load with CefSharp
Asked Answered
M

3

12

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
    }
Middleaged answered 18/4, 2017 at 0:21 Comment(1)
Those examples are out of date. Read github.com/cefsharp/CefSharp/wiki/General-Usage#handlersPsychophysiology
M
20

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');");
  }
};
Middleaged answered 18/4, 2017 at 2:39 Comment(1)
Hi @james-d do you maybe know how to ensure the injected javascript is loaded before the content finishes loading? I test with simple empty HTML page and add the JS as in your example of DOMContentLoaded however sometimes it gets fired and sometimes not depends on luck of which is loaded first :(Paxon
A
2

i've used LoadingStateChanged function as below:

browser.LoadingStateChanged += Browser_LoadingStateChanged;

private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
{
    if (e.IsLoading == false)
     {
        //All Resources Have Loaded
     }
}
Atherosclerosis answered 15/8, 2022 at 11:7 Comment(0)
M
0

In some cases, I will wait for the specific element appears instead of waiting for browser complete loading. So if you still want to wait for the page complete loading, you can try @Royals way

Myrmecology answered 2/1, 2019 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.