Preamble
I'm using the WebBrowser
control, which a user will interact with, so a solution will need to work with a visible WebBrowser
control.
Question
How do I check if an element has an anchor as a child? All browsers are able to distinguish that an element contains an anchor (<a href=""...
), and offers "open in new tab" functionality. That is what I am attempting to replicate. However, when I right click on a HtmlElement
I'm only able to obtain the parent element.
Example
Taking the BBC website as an example, when I right click on the highlighted element (picture below), my output is DIV
, but viewing the source code there is an anchor element as a child of this div
.
SSCCE
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace BrowserLinkClick
{
public partial class Form1 : Form
{
private WebBrowser wb;
private bool firstLoad = true;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wb = new WebBrowser();
wb.Dock = DockStyle.Fill;
Controls.Add(wb);
wb.Navigate("http://bbc.co.uk");
wb.DocumentCompleted += wb_DocumentCompleted;
}
private void Document_MouseDown(object sender, HtmlElementEventArgs e)
{
if (e.MouseButtonsPressed == MouseButtons.Right)
{
HtmlElement element = wb.Document.GetElementFromPoint(PointToClient(MousePosition));
//I assume I need to check if this element has child elements that contain a TagName "A"
if (element.TagName == "A")
Debug.WriteLine("Get link location, open in new tab.");
else
Debug.WriteLine(element.TagName);
}
}
private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (firstLoad)
{
wb.Document.MouseDown += new HtmlElementEventHandler(Document_MouseDown);
firstLoad = false;
}
}
}
}
Please test any proposed solution using the BBC website and the highlighted headline (the headline changes, but the DOM remains the same).
You have to get the child elements of element
before checking if it's an anchor:
HtmlElement element = wb.Document.GetElementFromPoint(PointToClient(MousePosition));
foreach (HtmlElement child in element.Children)
{
if (child.TagName == "A")
Debug.WriteLine("Get link location, open in new tab.");
}
To access the needed properties you need to cast the HtmlElement
to one of the unmanaged MSHTML interfaces, e.g. IHTMLAnchorElement
You have to add Microsoft HTML Object Library
COM reference to your project.
(The file name is mshtml.tlb
.)
foreach (HtmlElement child in element.Children)
{
if (String.Equals(child.TagName, "a", StringComparison.OrdinalIgnoreCase))
{
var anchorElement = (mshtml.IHTMLAnchorElement)child.DomElement;
Console.WriteLine("href: [{0}]", anchorElement.href);
}
}
There are plenty of such interfaces but MSDN will help you choose. :)
Scripting Object Interfaces (MSHTML)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With