我正在开发一个简单的应用程序,它自动浏览包含两个下拉菜单和一个按钮的页面。该页面如下所示:
------ ------- 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
生成的新值?
答案 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”事件完成。