2011-03-02 42 views
5

我正在研究一个简单的应用程序,该应用程序会在包含两个下拉菜单和一个按钮的页面中自动浏览。该网页看起来是这样的:c#webBrowser.Document:在回发后重新加载页面

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

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

- -----按钮---------

现在,问题是,通过Dropdown1选择是动态生成的DropDown2内容。

我在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中生成的新值?

回答

2

我发现onChange事件后通过调用“__doPostBack”脚本找到解决方案。当我调用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

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

 
|---> 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或类似的操作,以便经过一段时间(只要回发发生),然后可以继续设置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 

有这样做的更优雅的方式,但是这可能是最简单的解释。

+0

我想到了这一点,但“DocumentCompleted”处理程序没有运行后回发。在dropDown1中选择一个项目只会触发一个函数来填充DropDown2。所以Documentcompleted被激发一次。另外还有一点需要注意的是,当我在onChange之后延迟System.Threading.Thread.Sleep(5000);该线程只是等待完成回发5秒,它不工作..任何其他建议? – dreampowder 2011-03-02 15:01:55

0

谢谢你。我一直在寻找解决类似问题的日子...... 在我的情况下,我有一个下拉菜单,列表中的项目在“onchange”事件中更新。调用_ _doPostBack更新WebBrowserReadyState允许我在等待“onchange”事件完成之前完成新的下拉列表值。

+0

你很好,我很高兴我能帮上忙 – dreampowder 2013-12-23 11:59:22

相关问题