2

I have a TABLE Element in the current Document of a WebBrowser control.
I want to be able to color a Cell when my cursor is on it, when I press the A Key

Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
        htmlDocument1 = WebBrowser1.Document
        AddHandler htmlDocument1.MouseOver, AddressOf Me.gettd
End Sub

Public Sub gettd(ByVal sender As Object, ByVal e As System.Windows.Forms.HtmlElementEventArgs)
    Dim theElementCollection As HtmlElementCollection
    theElementCollection = WebBrowser1.Document.GetElementsByTagName("td")
    For Each curElement As HtmlElement In theElementCollection
        e.ToElement.Style = "background-color: orange;"
    Next
End Sub

Setting KeyPreview = True:

Public Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As KeyEventArgs) Handles Me.KeyDown
   If e.KeyCode = Keys.A Then
   ...
   end if
End Sub

How else can I achieve this?

Jimi
  • 29,621
  • 8
  • 43
  • 61
al78310
  • 83
  • 9

1 Answers1

1

A few changes are required:

  • The DocumentCompleted event can be used to add handlers to other events, but you have to remember that this event is raised multiple times per URI navigated: you're adding a multitude of handlers to the MouseOver event.
    It's simpler, in this case, to add a handler when the URI has been Navigated and remove it when we're Navigating to another.
    Also, read the notes here: How to get an HtmlElement value inside Frames/IFrames?

  • Instead of parsing the whole collection of Elements in the Document, we can simply use the Document.GetElementFromPoint() method, passing the e.ClientMousePosition value provided by the MouseOver or MouseMove events as the current Point position.

  • The Form's KeyDown event cannot be used to trap keys pressed - even with KeyPreview set to True - when other controls capture the input. You can get that key press overriding the Form's ProcessCmdKey, since it's called when messages are pre-processed.

  • Always check for null before accessing a HtmlElement or its properties. E.g., string properties never initialized are null (Nothing), not String.Empty.

Add this code to a Form, then navigate to a Html Page:

webBrowser1.Navigate("[Some URI]")

I've added a toggle function, to set the current Cell's Style to a background-color value when Keys.A is pressed and set it back when it's pressed again. Here, hard-coded to white, but you can add some logic to save the previous style, if required.

Public Class FormBrowser
    Private trackedElement As HtmlElement = Nothing
    Private elementColorOrange As String = "background-color: orange;"
    Private elementColorWhite As String = "background-color: white;"

    Private Sub webBrowser1_Navigating(sender As Object, e As WebBrowserNavigatingEventArgs) Handles webBrowser1.Navigating
        If webBrowser1.Document Is Nothing Then Return
        RemoveHandler webBrowser1.Document.MouseOver, AddressOf OnBrowserMouseOver
    End Sub

    Private Sub webBrowser1_Navigated(sender As Object, e As WebBrowserNavigatedEventArgs) Handles webBrowser1.Navigated
        AddHandler webBrowser1.Document.MouseOver, AddressOf OnBrowserMouseOver
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
        If keyData = Keys.A Then
            If trackedElement IsNot Nothing AndAlso trackedElement.TagName = "TD" Then
                Dim currentStyle As String = trackedElement.Style & ""
                trackedElement.Style = If(currentStyle.Contains(elementColorOrange), elementColorWhite, elementColorOrange)
                Return True
            End If
        End If
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function
End Class

Private Sub OnBrowserMouseOver(sender As Object, e As HtmlElementEventArgs)
    Dim doc = DirectCast(sender, WebBrowser).Document
    If doc Is Nothing Then Return
    trackedElement = doc.GetElementFromPoint(e.ClientMousePosition)
    txtElmName.Text = trackedElement?.OuterHtml
    txtElmValue.Text = trackedElement?.InnerHtml
End Sub

This is how it works:

WebBrowser Track Mouse Position

Jimi
  • 29,621
  • 8
  • 43
  • 61