65.9K
CodeProject 正在变化。 阅读更多。
Home

WebBrowser 元素事件和值

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2013年2月16日

CPOL

2分钟阅读

viewsIcon

86587

downloadIcon

3226

程序化地获取/设置 WebBrowser 按钮元素事件和输入元素值,无需 Web 服务器。

引言

我正在为 Intertexti 添加一个功能,在该功能中,我可以创建 HTML 表单并记录用户特定于笔记卡的数据。 此外,我希望能够这样做,而无需后端的服务器。 想法是能够获取/设置文本输入字段的值,并捕获单选按钮、复选框和普通按钮的鼠标点击事件。 我对如何做到这一点的搜索带我去了几个地方

将委托附加到 webbrowser HTML 元素

获取 webbrowser 文本框中的文本 

HTML DOM 事件名称列表 

演示程序使用 .NET 的 WebBrowser 控件(如果你阅读了 Intertexti 文章,是的,我放弃了 webkit.net,即使我随后让 open-webkit-sharp 编译并工作,它也有很多问题,不值得继续研究。)

测试表单

我在测试程序中硬编码了 HTML 以呈现上述网页

browser.DocumentText="<form>\r\n" +
  "First name: <input id='firstname' type='text' name='firstname'/><br/>\r\n" +
  "Last name: <input id='lastname' type='text' name='lastname'/><br/>\r\n" +
  "Password: <input id='password' type='password' name='pwd'/><br><br/>\r\n" +
  "<input type='radio' id='male' name='sex' value='male'/>Male<br/>\r\n" +
  "<input type='radio' id='female' name='sex' value='female'/>Female<br/><br/>\r\n" +
  "<input type='checkbox' id='bike' name='vehicle' value='Bike'/>I have a bike<br/>\r\n" +
  "<input type='checkbox' id='car' name='vehicle' value='Car'/>I have a car <br/><br/>\r\n" +
  "<input type='button' id='ok' value='OK'/><br/>\r\n" +
  "<input type='button' id='cancel' value='Cancel'/><br/><br/>\r\n" +
  "</from>";  

DocumentCompleted 事件

事件处理程序必须在文档加载后才能连接,因此我们需要首先处理 DocumentCompleted 事件

public class Form1()
{
  public Form1()
  {
    ...
    browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(OnDocumentCompleted);
  }

  protected void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
  {
    WireUpButtonEvents();
  }
}

连接事件处理程序

对于实际的元素连接,我们使用元素方法 AttachEventHandler。 不幸的是,当实际调用事件时,sender 参数为 null,因此我们改为利用匿名方法将事件转发给我们的实际处理程序,并将元素实例作为 sender 提供。 但是,这意味着我们需要匿名方法中的元素实际实例,因此使用索引循环而不是更典型的 foreach 迭代器。

最后,类型为单选按钮、复选框和按钮的元素通过连接 DOM "onclick" 属性传递给 OnElementClicked 处理程序,而文本元素通过连接 DOM "onblur" 属性传递给 OnElementLostFocus 处理程序。

protected void WireUpButtonEvents()
{
  HtmlElementCollection elements = browser.Document.GetElementsByTagName("input");

  // We have to use this form because of the lambda expression that is used to pass
  // in the element instance to the handler. This is the only way to actually get
  // the element instance, as the instance is not passed in if we just provide the
  // event sink method name.
  for (int i=0; i<elements.Count; i++)
  {
    HtmlElement el = elements[i];
    string elType = el.GetAttribute("type");

    switch (elType)
    {
      case "radio":
      case "checkbox":
      case "button":
      {
        // We need the element instance to know what was clicked.
        el.AttachEventHandler("onclick", (sender, args) => OnElementClicked(el, EventArgs.Empty));
        break;
      }

      case "text":
      {
        // We need the element instance to know what was clicked.
        el.AttachEventHandler("onblur", (sender, args) => OnElementLostFocus(el, EventArgs.Empty));
        break;
      }
    }
  }
}

事件处理程序

最后,事件处理程序仅在浏览器控件下面的 textbox 中报告事件的发生

protected void OnElementClicked(object sender, EventArgs args)
{
  HtmlElement el = sender as HtmlElement;
  string elType = el.GetAttribute("type");
  string elName = el.GetAttribute("name");
  string elValue = el.GetAttribute("value");
  tbMessages.Text += "Clicked: " + elType + " " + elName + " " + elValue + "\r\n";
}

protected void OnElementLostFocus(object sender, EventArgs args)
{
  HtmlElement el = sender as HtmlElement;
  string elType = el.GetAttribute("type");
  string elName = el.GetAttribute("name");
  string elValue = el.GetAttribute("value");
  tbMessages.Text += elType + " " + elName + " " + elValue + "\r\n";
}

恢复状态

如果你点击表单上的“设置数据”按钮,则会设置各种输入元素的状态

protected void SetFormState()
{
  browser.Document.GetElementById("firstname").SetAttribute("value", "Marcia");
  browser.Document.GetElementById("lastname").SetAttribute("value", "JohnDoe");
  browser.Document.GetElementById("female").SetAttribute("checked", "1");
  browser.Document.GetElementById("bike").SetAttribute("checked", "");
  browser.Document.GetElementById("car").SetAttribute("checked", "1");
}

请注意,要取消选中复选框,需要将一个空字符串作为属性值传递。 另请注意,不需要“取消选中”单选按钮 - 浏览器会处理由 name 属性分组的所有单选按钮的此状态更改。

结论

希望此代码已简洁地说明了如何挂钩到 web 浏览器的事件,以通过编程方式响应按钮点击和文本值更改,以及如何将 web 浏览器的可编辑控件恢复到特定状态。

© . All rights reserved.