Click here to Skip to main content
Click here to Skip to main content

WebBrowser Element Events and Values

, 16 Feb 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marc Clifton

United States United States
Marc is the creator of two open source projects, MyXaml, a declarative (XML) instantiation engine and the Advanced Unit Testing framework, and Interacx, a commercial n-tier RAD application suite.  Visit his website, www.marcclifton.com, where you will find many of his articles and his blog.
 
Marc lives in Philmont, NY.

Comments and Discussions

 
Questiononchange event its not fired PinmemberMember 995461530-Oct-14 1:45 
GeneralThanks Pinmemberemarti1-Feb-14 9:28 
GeneralThank you Pinmemberlatipovsharif26-Nov-13 0:59 
GeneralMy vote of 5 PinprofessionalDrABELL12-Aug-13 8:24 
QuestionThank You! PinmemberJim Meadors2-Apr-13 20:25 
AnswerRe: Thank You! PinprotectorMarc Clifton3-Apr-13 5:04 
QuestionWant to create a specific functionality with web browser control and html button c# PinmemberTridip Bhattacharjee17-Feb-13 21:29 
GeneralOn the web browser PinmemberBrisingr Aerowing16-Feb-13 16:43 
GeneralRe: On the web browser PinprotectorMarc Clifton17-Feb-13 2:38 
GeneralRe: On the web browser PinmemberBrisingr Aerowing17-Feb-13 10:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 16 Feb 2013
Article Copyright 2013 by Marc Clifton
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid