Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

WebBrowser Element Events and Values

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
16 Feb 2013CPOL2 min read 83.5K   3.2K   21   9
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)


Written By
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions

 
GeneralThanks Pin
emarti1-Feb-14 8:28
emarti1-Feb-14 8:28 
GeneralThank you Pin
latipovsharif25-Nov-13 23:59
latipovsharif25-Nov-13 23:59 
GeneralMy vote of 5 Pin
DrABELL12-Aug-13 7:24
DrABELL12-Aug-13 7:24 
QuestionThank You! Pin
Jim Meadors2-Apr-13 19:25
Jim Meadors2-Apr-13 19:25 
Your article got me over the hump on trying to do this exact thing and I am now practicing it and putting it into application. Thumbs Up | :thumbsup:

<sig notetoself="think of a better signature">
<first>Jim
<last>Meadors


AnswerRe: Thank You! Pin
Marc Clifton3-Apr-13 4:04
mvaMarc Clifton3-Apr-13 4:04 
QuestionWant to create a specific functionality with web browser control and html button c# Pin
Tridip Bhattacharjee17-Feb-13 20:29
professionalTridip Bhattacharjee17-Feb-13 20:29 
GeneralOn the web browser Pin
Brisingr Aerowing16-Feb-13 15:43
professionalBrisingr Aerowing16-Feb-13 15:43 
GeneralRe: On the web browser Pin
Marc Clifton17-Feb-13 1:38
mvaMarc Clifton17-Feb-13 1:38 
GeneralRe: On the web browser Pin
Brisingr Aerowing17-Feb-13 9:35
professionalBrisingr Aerowing17-Feb-13 9:35 

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

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