且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Webbrowser:当托管网页上的链接触发DocumentCompleted时,排序活动

更新时间:2023-11-03 22:29:40

我在这里发布解决方案,我可以找到这个问题:我写了一个扩展方法HtmlElement类型如下:

  public static bool WaitForAvailability(此HtmlElement标记,字符串ID,HtmlDocument documentToExtractFrom,long maxCycles)
{
bool cond = true;长计数器= 0;
while(cond)
{
Application.DoEvents();
tag = documentToExtractFrom.GetElementById(id);
if(tag!= null)
cond = false;
Thread.SpinWait(50000);
counter ++;
if(counter> maxCycles)
return false;
}
返回true;
}

这样可以等待一段时间,在页面


中确实可用

Given this method to work on a HTML page in a webbrowser:

    bool semaphoreForDocCompletedEvent;

                private void button12_Click(object sender, EventArgs e)
                        {
                            checkBox1.Checked = false; //unchecked if the NAvigating event is fired and Checked after DocumentCompleted is fired, only to have a visual reference on the Form
                            HtmlDocument doc = Program.wb.Document;
                            HtmlElement ele = doc.GetElementById("menuTable");
                            foreach (HtmlElement sub in ele.All)
                            {
                                if (sub.GetAttribute("href").Contains("something"))
                                {
                                    ele = sub;
                                    break;
                                }
                            }
//PHASE 1: clicking on a Web link to navigate to a page that contains other buttons and links                       object obj = ele.DomElement;
                            System.Reflection.MethodInfo mi = obj.GetType().GetMethod("click");
                            mi.Invoke(obj, new object[0]);
//PHASE 2: Waiting for document completed in order to be sure the document is fully loaded

                            semaphoreForDocCompletedEvent = WaitForDocumentCompleted();
                            if (!semaphoreForDocCompletedEvent)
                                throw new Exception("casino in giro!");

                            ele = doc.GetElementByI("button1").FirstChild.FirstChild.FirstChild.NextSibling;
//PHASE 3: clicking on a Web button to open a form

                            obj = ele.DomElement;
                            mi = obj.GetType().GetMethod("click");
                            mi.Invoke(obj, new object[0]);
//PHASE 4: displaying a modal MEssageBox that annoy the user a lot

                            if (checkBox1.Checked == false)
                                MessageBox.Show("non c'è stato document completed");
                            checkBox1.Checked = false;

//PHASE 5: submitting the form (that does not need any imput to be filled in)

                            ele = doc.GetElementById("planet");
                            ele = ele.FirstChild.NextSibling.NextSibling;

                            obj = ele.DomElement;
                            mi = obj.GetType().GetMethod("submit");
                            mi.Invoke(obj, new object[0]);
                        }

    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                Program.toBox = Program.wb.Document.Body.InnerHtml.ToString();
                if (Program.wb.ReadyState == WebBrowserReadyState.Complete)
                {
                    checkBox1.Checked = true;
                    IsBusy = false;
                }
            }

        private bool WaitForDocumentCompleted()
                { 
                    while (IsBusy)
                    {
                        Application.DoEvents();
                        Thread.SpinWait(1000);
                    }
                    return true;
                }

I need to understand why this code runs like a charm when the messagebox is displayed and does not when it is commented out. My doubts can be resumend in these questions:

1) how is the flow of the code when the message box is part of the program and when it is not? I mean is the code blocked up to the user presses ok?

2) the phase I indicated above with number 3 fires some javascript in the page that does not issue a Navigating event (therefore no DocumentCompleted) but gives access to some hidden HTML not reachable without clicking on a A tag. In practice it just changes the InnerHtml of a tag, creating a FORM in it.

3) I tried to implement several solutions for phase 4, a Message box as indicated here up, a ThreadSleep(), a SpinWait() and even a for loop messing everything up, but all those solutions seem not to let the Webbrowser proceeding in visualizing the form on screen. Only the message box brings it up to screen, even if the user is very fast in pressing OK and closing it.

4) I need to find a solution that does not involve external (user) input (such the Messagebox to be closed) in order to wait for the form to appear completerly loaded on the screen, but no events come to help.

Some more data to evaluate the case: - the code I wrote is good for the aim, I tried to split it into 3 buttons to manage the timing by hand and it works fine. - the document completed cannot be used for switching between code splits, as there are around 300 pages automated and each page can have 10-15 methods to automate them, it's impossible to manage a single eventhandler for all of them, without builind up a neverending Switch struct. I would try t avoid it if possible. - i've found some interesting issues of other users like the following but without solution for my case:

InvalidCastException with WebBrowser.IsBusy or ReadyState (VB .NET)

Detect when AJAX changes HTML in a DIV in WebBrowser

http://www.techtalkz.com/vb-net/374234-vb-net-webbrowser-control-how-capture-javascript-events-statusbar-changed-mouseclick-etc.html

Could somebody give me a hand.

Sorry it is my first thread, hope I've been clear. Tks

I'm posting here the solution i've been able to find for this problem: I wrote an extension method for the HtmlElement type as follows:

public static bool WaitForAvailability(this HtmlElement tag, string id, HtmlDocument   documentToExtractFrom, long maxCycles)
{ 
    bool cond = true; long counter = 0; 
        while (cond) 
        { 
        Application.DoEvents(); 
        tag = documentToExtractFrom.GetElementById(id);
         if (tag != null) 
            cond = false;
         Thread.SpinWait(50000);
         counter++; 
        if (counter > maxCycles) 
            return false; 
        } 
    return true;
 }

This allows the required tag to be waited for up to the moment when it will be really available in the page