在代码中控制一个c# WebBrowser对象来按下一个最初被禁用的按钮
本文关键字:下一个 按钮 对象 WebBrowser 控制 代码 一个 | 更新日期: 2023-09-27 18:10:12
我正在将一个网页加载到WebBrowser
对象中,并且该网页的一部分有一个具有3个属性的HTML Form
,即两个Select
属性和一个Submit
类型的Input
属性。两个Select
属性表示不同的选择列表,做出选择后按下与Input
属性对应的按钮,从而加载数据。当程序运行并且WebBrowser
对象可见时,我可以手动使用鼠标和网页正确加载数据,就像它在浏览器中运行一样,例如Chrome。然而,当我试图写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;
}
}
我做错了什么?
这个问题可能与Application.DoEvents
有关(顺便说一句,即使对于UI自动化来说,这也是一个邪恶的东西)。它所做的消息循环泵的单次迭代可能还不够。理想情况下,您应该使用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);
// ...
}
然而,如果你选择这条路,代码必须是异步的。
如果没有帮助,只要尝试手动启用按钮:
HtmlElement button = getElement("input", "filter-nav-submit");
button.Enabled = true;