2

I need the correct css path from a webpage, which will be displayed in my WPF application(to use it later with HTMLAgilityPack and/or Fizzler).

Something like this, to "copy css-path" or xpath(FireBug), should be the final goal.

I also found some interesting post like:

They all use "webBrowser.Document.GetElementFromPoint", "webBrowser.GetElementFromPoint" or "PointToClient", but I can not find it in any library and not even on msdn.microsoft(WebBrowser Class)

By the way I use the "WebBrowserControl" from visual studio 2010 toolbox to display my webpage.

Then I found some function on the client-side, but this can not be the thing they meant(javascript)...

updated:12 th june, 08:15 pm

This is actually a nice post by "dick":

 private void myBrowser_LoadCompleted(object sender, NavigationEventArgs e) { dynamic doc = myBrowser.Document; dynamic htmlText = doc.documentElement.InnerHtml; string htmlstring = htmlText; } 

This works, but this stands in no relation to my WPF element. I get only the html but not the corresponding element. I could search for the text in that html doc, but if it appears more than once, its is not unique anymore.

updated: 13 th june, 07:15 a.m

Based on this tutorial I found a workaround.

I included this namespace in my ".xaml":

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 

Then I added the the old winforms browser:

<WindowsFormsHost Name="wfhSample" Margin="372,12,12,205" MouseLeftButtonDown="wfhSample_MouseLeftButtonDown"> <WindowsFormsHost.Child> <wf:WebBrowser /> </WindowsFormsHost.Child> </WindowsFormsHost> 

Added to my "MainWindow()" a starting value:

MainWindow(){ (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.google.de/"); } 

The actual part, to get the element:

 /* System.Drawing.Point point = System.Windows.Forms.Control.MousePosition; ...myMethod(..., (wfhSample.Child as System.Windows.Forms.WebBrowser), point.X, point.Y); */ ...myMethod(...,System.Windows.Forms.WebBrowser refWebBrowser2,Int32 valScreenX, Int32 valScreenY,....){ Point refPoint = refWebBrowser2.PointToClient(new Point(valScreenX, valScreenY)); System.Windows.Forms.HtmlElement refHtmlElement = refWebBrowser2.Document.GetElementFromPoint(refPoint); //System.Drawing() return refHtmlElement.TagName; } 

The only problem,which is left by now is that the event handler does not fire(I added them over the properties window):

//winforms-browser private void wfhSample_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MessageBox.Show("old"); } //wpf-browser private void browser_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MessageBox.Show("new"); } 

Why can't I overwrite the event handler(not even the right button) ?

updated: 13 th june, 07:45 a.m

This could be an useful article, I will check this out.

updated: 16 th june, 07:00 a.m

Now I found a solution, where I can handle an event for a wpf-webbrowser, but not for the old winforms-browser.

 //new WPF webbrowser private void browser_LoadCompleted(object sender, NavigationEventArgs e) { mshtml.HTMLDocument doc; doc = (mshtml.HTMLDocument)browser.Document; mshtml.HTMLDocumentEvents2_Event iEvent; iEvent = (mshtml.HTMLDocumentEvents2_Event)doc; iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(NewClickEventHandler); } private bool NewClickEventHandler(mshtml.IHTMLEventObj e) { //the click event handler works, but I have no access to "GetElementFromPoint" // it does not exist //Point refPoint = browser.PointToClient(new Point(valScreenX, valScreenY)); //System.Windows.Forms.HtmlElement refHtmlElement = browser.Document.GetElementFromPoint(refPoint); //return refHtmlElement.TagName; //because the new wpf control does not support for example 'GetElementFromPoint()' // I need to get the html controls conntected to the wpf cursor } 

This helped me and I changed the event handling for Winforms webbrowser in my wpf application to:

//old Winforms webbrowser private void wfhSample_ChildChanged(object sender, System.Windows.Forms.Integration.ChildChangedEventArgs e) { //registering the event here, //calling "OldClickEventHandler" does not work I get a "NullReferenceException" for "_docEvent" HTMLDocumentEvents2_Event _docEvent= (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler); } private bool OldClickEventHandler(mshtml.IHTMLEventObj e) { } 

At the moment I still do not get the element from the webbrowser which I selected in my WPF-application on the one hand I have a problem with an event for the old webforms webbrowser, where I get a "NullReferenceException"(actually it should not be null from my point of view) and on the other hand for my new(wpf) webbrowser control I can not access "GetElementFromPoint()" because it does not seem to exist for the wpf webbrowser control.

updated: 17 th june, 10:00 a.m

It seems, that

(HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; 

which is inside "wfhSample_ChildChanged" is not ready yet, because when I put the same statement:

(HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; 

into "NewClickEventHandler(mshtml.IHTMLEventObj e)" it has the required data in it(,but this is the wrong event handler).

So, now I need to find the correct/proper event handler for my old wpf browser.

updated: 17 th june, 11:30 a.m

Ok, now I found a solution based on this article, I changed my code to:

 private void wfhSample_Loaded(object sender, RoutedEventArgs e) { bool complete = false; (wfhSample.Child as System.Windows.Forms.WebBrowser).DocumentCompleted += delegate { if (complete) return; complete = true; // DocumentCompleted is fired before window.onload and body.onload (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.Window.AttachEventHandler("onload", delegate { // Defer this to make sure all possible onload event handlers got fired System.Threading.SynchronizationContext.Current.Post(delegate { // try webBrowser1.Document.GetElementById("id") here //System.Windows.MessageBox.Show("window.onload was fired, can access DOM!"); var bla = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; HTMLDocumentEvents2_Event _docEvent = (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler); }, null); }); }; (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.example.com"); } private bool OldClickEventHandler(mshtml.IHTMLEventObj e) { System.Drawing.Point point = System.Windows.Forms.Control.MousePosition; System.Drawing.Point refPoint = (wfhSample.Child as System.Windows.Forms.WebBrowser).PointToClient(new System.Drawing.Point(point.X, point.Y)); System.Windows.Forms.HtmlElement refHtmlElement = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.GetElementFromPoint(refPoint); var restult = refHtmlElement.TagName; //this is what I need for the first time,to continue return true; } 

And the event handling for the old control works :)

But the "var restult = refHtmlElement.TagName;" returns a "NullReferenceException", there seems to be something wrong with the coordinates.

As soon as I have a solution I will post it or if you have an idea you can help as well:)

0

1 Answer 1

0

Ok,I found a solution including the winform webbrowser into my wpf application(take a look at my question regarding, processes and resources):

1.The .xaml part(namespace)(more details):

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 

2.The .xaml part(WebBrowser)(more details):

<WindowsFormsHost Name="wfhSample" Margin="372,12,12,205" Loaded="wfhSample_Loaded"> <WindowsFormsHost.Child> <wf:WebBrowser /> </WindowsFormsHost.Child> </WindowsFormsHost> 

3.The code behind file(more details):

 private void wfhSample_Loaded(object sender, RoutedEventArgs e) { bool complete = false; (wfhSample.Child as System.Windows.Forms.WebBrowser).DocumentCompleted += delegate { if (complete) return; complete = true; // DocumentCompleted is fired before window.onload and body.onload (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.Window.AttachEventHandler("onload", delegate { // Defer this to make sure all possible onload event handlers got fired System.Threading.SynchronizationContext.Current.Post(delegate { // try webBrowser1.Document.GetElementById("id") here //System.Windows.MessageBox.Show("window.onload was fired, can access DOM!"); var bla = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; HTMLDocumentEvents2_Event _docEvent = (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument; _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler); }, null); }); }; (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.example.com"); } private bool OldClickEventHandler(mshtml.IHTMLEventObj e) { System.Drawing.Point point = System.Windows.Forms.Control.MousePosition; System.Drawing.Point refPoint = (wfhSample.Child as System.Windows.Forms.WebBrowser).PointToClient(new System.Drawing.Point(point.X, point.Y)); System.Windows.Forms.HtmlElement refHtmlElement = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.GetElementFromPoint(refPoint); var restult = refHtmlElement.TagName; return true; } 

4.To get the full CSS-Path or XPath you could use Fizzler, HTMLAgilityPack(this).

Sometimes it is a little buggy(resizing window, changing tabs), the event handler does not fire anymore.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.