Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WebBrowser Element Events and Values

0.00/5 (No votes)
16 Feb 2013 1  
Sinking WebBrowser button element events and getting/setting input element values programmatically, without a web server.

Introduction

I am in the process of adding a feature to Intertexti in which I can create HTML forms and log the user's data specific to the notecard.  Furthermore, I want to be able to do this without requiring a back-end server.  The idea is to be able to get/set the values for text input fields and to capture mouse click events for radio buttons, checkboxes, and normal buttons.  My search for how to do this took me two a few places:

Attaching delegates to webbrowser HTML elements

Getting text in a webbrowser textbox 

A list of HTML DOM event names 

The demonstration program utilizes .NET's WebBrowser control (and if you read the Intertexti article, yes, I'm ditching webkit.net and, even though I subsequently got open-webkit-sharp to compile and work, it has so many problems it wasn't worth persuing.)

The Test Form

I hard-coded the HTML in the test program to render the above web page:

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>";  

The DocumentCompleted Event

Event handlers cannot be wired up until the document has loaded, hence we need to first handle the DocumentCompleted event:

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

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

Wiring Up Event Handlers

For the actual element wireups, we use the element method AttachEventHandler.  Unfortunately, when the event is actually called, the sender parameter is null, so we instead take advantage of an anonymous method to forward the event to our real handler, with the element instance provided as the sender.  However, this means we need the actual instance of the element in the anonymous method, hence the indexed loop rather than a more typical foreach iterator.

Lastly, the elements of type radio button, checkbox, and button are passed to the OnElementClicked handler by wiring up the DOM "onclick" property, whereas text elements are passed to the OnElementLostFocus handler by wiring up the DOM "onblur" property. 

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;
      }
    }
  }
}

The Event Handlers

Lastly, the event handlers simply report the event occurrence in the textbox below the browser control:

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";
}

Restoring State

If you click on the "Set Data" button on the form, the state of the various input elements are set:

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");
}

Note that to uncheck a checkbox, an empty string is passed as the attribute value.  Also note that one does not need to "uncheck" a radio button - the browser handles this state change for all radio buttons grouped by the name attribute.

Conclusion

Hopefully this code has concisely illustrated how to hook into the web browser's events to respond programmatically to button clicks and text value changes, as well as how to restore the web browser's editable controls to a specific state.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here