我正在将一个网页加载到一个WebBrowser对象中,该网页的一部分包含一个具有3个属性的HTMLForm,即两个Select属性和一个Submit类型的Input属性。这两个Select属性表示不同的选择列表,做出选择后,按下与导致加载数据的Input属性对应的按钮。当程序正在运行并且WebBrowser对象可见时,我可以手动使用鼠标,网页就会正确加载数据,就像它在浏览器中运行一样。但是,当我尝试编写C#来控制WebBrowser对象时,它不起作用。
第一次加载网页时,表单上的Input属性将灰显。但是,使用鼠标在两个Select属性中的任何一个中进行选择会导致启用Input属性,并将颜色更改为绿色。我必须进行选择的C#代码不会复制该行为,因为执行选择的代码(如下所示)不会启用Input属性。我不清楚导致启用Input属性的代码位于何处,但我一直希望我不需要解决这个问题。
表单的HTML代码如下所示:
<form method="get" id="filter-nav">
<fieldset>
<label for="group-drop-down">Show me:</label>
<select id="drop-down-1" name="filter">
<option value="">drop-down-1-heading</option>
<optgroup label="optgroup-1-label" id="optgroup-1" >
<option value="optgroup-1-choice-1" > Choice-1 </option>
<option value="optgroup-1-choice-2" > Choice-2 </option>
</optgroup>
<optgroup label="optgroup-2-label" id="optgroup-2" >
<option value="optgroup-2-choice-3" > Choice-3 </option>
<option value="optgroup-2-choice-4" > Choice-4 </option>
</optgroup>
</select>
<span>OR</span>
<select id=""drop-down-2" name="filter">
<option value="">drop-down-2-heading</option>
<optgroup label="optgroup-3-label" id="optgroup-3" >
<option value="optgroup-3-choice-5" > Choice-5 </option>
<option value="optgroup-3-choice-6" > Choice-6 </option>
</optgroup>
<optgroup label="optgroup-4-label" id="optgroup-4" >
<option value="optgroup-4-choice-7" > Choice-7 </option>
<option value="optgroup-4-choice-8" > Choice-8 </option>
</optgroup>
</select>
<input id="filter-nav-submit" type="submit" value="Update" />
</fieldset>
</form>我用来尝试和控制它的C#代码是以下类的LoadData()方法
private class WebBrowserHelper {
WebBrowser wb;
public void LoadData() {
HtmlElement select1 = getElement("select", "drop-down-1");
select1.Focus();
Application.DoEvents();
select1.SetAttribute("Value", "optgroup-1-choice-2");
Application.DoEvents();
select1.InvokeMember("change");
Application.DoEvents();
// at this point, the select1 dropdown shows the right value
// but the button corresponding to the input attribute is still greyed out
}
public HtmlElement getElement(string tagName, string IdName) {
HtmlElementCollection theElementCollection = wb.Document.GetElementsByTagName(tagName);
foreach (HtmlElement curElement in theElementCollection) {
object id = curElement.GetAttribute("id");
if (id != null && id.Equals(IdName)) return curElement;
}
return null;
}
}我做错了什么?
发布于 2014-06-26 12:57:30
这个问题可能与Application.DoEvents有关(即使对于UI自动化,BTW也是一个邪恶的东西)。它所做的消息循环泵的单次迭代可能是不够的。理想情况下,您应该使用async/await和一些异步延迟:
public async Task LoadDataAsync() {
HtmlElement select1 = getElement("select", "drop-down-1");
select1.Focus();
await Task.Delay(200);
select1.SetAttribute("Value", "optgroup-1-choice-2");
await Task.Delay(200);
select1.InvokeMember("change");
await Task.Delay(200);
// ...
}然而,如果你走这条路,代码必须是异步"all the way down"。
如果这样也没用,那就试着手动启用这个按钮:
HtmlElement button = getElement("input", "filter-nav-submit");
button.Enabled = true;https://stackoverflow.com/questions/24415591
复制相似问题