在代码中控制一个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;
    }
}

我做错了什么?

在代码中控制一个c# WebBrowser对象来按下一个最初被禁用的按钮

这个问题可能与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;