c # webBrowser.Document: перезагрузка страницы после обратной передачи - PullRequest
5 голосов
/ 02 марта 2011

Я работаю над простым приложением, которое автоматически просматривает страницу, которая содержит два раскрывающихся меню и кнопку.Страница выглядит следующим образом:

------ DropDown1 -------

------ DropDown2 -------

------- Кнопка ---------

Теперь проблема в том, что содержимое DropDown2 динамически генерируется выборомDropdown1.

Я написал такой код на c #:

private void webBrowser1_DocumentCompleted(object sender, 
        WebBrowserDocumentCompletedEventArgs e)
{
    HtmlElement elem = webBrowser1.Document.GetElementById("DropDown1");
    elem.SetAttribute("selectedIndex", "1");
    elem.RaiseEvent("onChange");
    HtmlElement elem = webBrowser1.Document.GetElementById("DropDown2");
    elem.SetAttribute("selectedIndex", "5");
    elem.RaiseEvent("onChange");
}

После вызова события onChange браузер загружает новые значения, но не могу получить и установитьDropDown2 значение, потому что документ все еще думает, что значения DropDown2 s пусты.

Как я могу получить и установить новые значения, которые генерируются в DropDown2?

Ответы [ 3 ]

2 голосов
/ 02 марта 2011

Я нашел решение, вызвав скрипт "__doPostBack" после вызова события onChange. когда я добавляю doPostBack, документ перезагружается, и я могу получить новые значения. вот код:

    private void BeginOperation()
    {
        webBrowser1.Navigate("somewebpage", false);
        Task = 0;
    }
    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        HtmlElement elem;

        switch (Task)
        {
            case 0:
                //HtmlDocument mydoc = webBrowser1.Document;
                 elem = webBrowser1.Document.GetElementById("ddlCity");
                MessageBox.Show(elem.All.Count.ToString());
                elem.SetAttribute("selectedIndex", "1");
                //elem.RaiseEvent("onChange");
                object[] args = {"someparameters"};
                webBrowser1.Document.InvokeScript("__doPostBack",args);
                Task++;
            break;
            case 1:
                elem = webBrowser1.Document.GetElementById("ddlDistrict");
                elem.SetAttribute("selectedIndex", "2");
                elem.RaiseEvent("onChange");
                object[] args2 = {"someparameters"};
                webBrowser1.Document.InvokeScript("__doPostBack",args2);
                Task++;
            break;
        }
     }
0 голосов
/ 22 декабря 2013

Спасибо вам за это. Я искал решение подобной проблемы в течение нескольких дней ... В моем случае у меня было одно выпадающее меню, для которого элементы в списке были обновлены во время события «onchange». Вызов _ _doPostBack обновляет WebBrowserReadyState, позволяя мне дождаться завершения события «onchange», прежде чем очищать новые значения раскрывающегося списка.

0 голосов
/ 02 марта 2011

Я подозреваю, что проблема, с которой вы сталкиваетесь, заключается в том, что написанный вами код не ожидает обратной передачи.Итак, что происходит ...

|---> The page finishes loading, triggering your DocumentCompleted method
|---> You set the selectedIndex on DropDown1
|---> You raise the onChange event for DropDown1
|       |---> The page starts posting-back (1)
|---> You (attempt to) set the selectedIndex on DropDown2
|---> You raise the onChange event for DropDown2
|       |---> The page starts posting-back (2)
|
...
...
...
|---> The page finishes re-loading from from postback (2)

По сути, вам нужно ждать после запуска обратной передачи для повторной загрузки страницы.Не элегантный, хрупкий и почти наверняка сломанный / неработающий способ сделать это состоит в том, чтобы вызвать Таймер или аналогичный, чтобы через определенный промежуток времени (столько времени, сколько требуется для обратной передачи) вызатем продолжите установку selectedIndex для DropDown2.Лучшим вариантом было бы сделать что-то вроде этого:

|---> The page finishes loading, triggering your DocumentCompleted method
|---> You attach a new EventHandler to DocumentCompleted that contains the 
|     code for changing the selectedIndex on DropDown2 and REMOVE this 
|     eventhandler
|---> You set the selectedIndex on DropDown1
|---> You raise the onChange event for DropDown1
|---> Your code in the DocumentCompleted handler finishes executing


|---> // This is the DocumentCompleted handler that you assign above
|---> You set the selectedIndex on DropDown2
|---> You raise the onChange event for DropDown2
|---> Your code in the DocumentCompleted handler finishes executing

Есть более элегантные способы сделать это, но это, вероятно, проще всего объяснить.

...