c#webBrowser.Document:回发后重新加载页面

时间:2011-03-02 13:43:44

标签: c# html webbrowser-control

我正在开发一个简单的应用程序,它自动浏览包含两个下拉菜单和一个按钮的页面。该页面如下所示:

  

------ ------- 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的值为空。

如何获取和设置DropDown2生成的新值?

3 个答案:

答案 0 :(得分:2)

我通过调用" __ 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;
        }
     }

答案 1 :(得分:0)

我怀疑您遇到的问题是因为您编写的代码不会等待回发发生。那么会发生什么......

|---> 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)

基本上,在触发重新加载页面的回发后,您需要做的是等待。这种不优雅,脆弱且几乎肯定会破坏/不工作的方式是触发Timer或类似的,以便在一段时间后(只要回发发生),您可以继续为DropDown2设置selectedIndex。更好的选择是做这样的事情:

|---> 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

有更优雅的方法可以做到这一点,但这可能是最简单的解释。

答案 2 :(得分:0)

谢谢你。几天来我一直在寻找类似问题的解决方案...... 就我而言,我有一个下拉菜单,列表中的项目在“onchange”事件期间更新。调用 _ _doPostBack会更新WebBrowserReadyState,这样我就可以在抓取新的下拉列表值之前等待“onchange”事件完成。