Embedded WebBrowser in Windows Form C# project - c#

I have a form with an embedded web browser control on it. I am currently using WebBrowser and use it like so:
webBrowser1.Navigate("about:blank");
HtmlDocument doc = this.webBrowser1.Document;
doc.Write(string.Empty);
String htmlContent = GetHTML();
doc.Write(htmlContent);
This writes the HTML correctly to the web browser control BUT it never clears the existing data and it just appends, so I end up with N web pages stacked on top of each other.
Is this the best control to use? If so why is it not clearing existing data?

You need to use:
HtmlDocument doc = this.webBrowser1.Document.OpenNew(true);
now the contents of the document will be cleared before writing.
All calls to Write should be preceded
by a call to OpenNew, which will clear
the current document and all of its
variables. Your calls to Write will
create a new HTML document in its
place. To change only a specific
portion of the document, obtain the
appropriate HtmlElement and set its
InnerHtml property.

Yes, it is.
You should be able to call the Clear method if you need to clear contents.
Check this article for in-depth details and sample code:
http://www.codeproject.com/KB/miscctrl/simplebrowserformfc.aspx

Call HtmlDocument.OpenNew between pages:
OpenNew will clear the previous loaded
document, including any associated
state, such as variables. It will not
cause navigation events in WebBrowser
to be raised.

Related

Is there an alternative to WebBrowser control for DOM traversal?

I am currently using a WebBrowser control in my Windows Forms application to navigate to a URL. Once I am at that URL, I use the FirstChild in conjunction with NextSibling methods of the HtmlElement class to walk the document tree from the WebBrowser.Document object.
The reason I do this is to get information from a page and store this information into a database.
Here is the crux of my question: Do I really need to use the WebBrowser class? I currently do not need to display the web page to the user, only some of the information found in the page.
Is there a better way to do this without relying on this class? Something solid which can do DOM traversal would be required, but as mentioned above, I do not need to display the web page.
Regards
Crouz
You can use a WebClient to download the HTML without displaying the page. You can then use something like HTML Agility Pack to create an HTMLDocument from the string.
Example:
using (WebClient wc = new WebClient())
{
string html = wc.DownloadString("http://www.foo.bar/"); // Change as required.
HtmlAgilityPack.HtmlDocument h = new HtmlAgilityPack.HtmlDocument();
h.LoadHtml(html);
}
Reason to use HTML Agility Pack:
The HtmlDocument class is a wrapper around the native IHtmlDocument2 COM interface.
You cannot easily create it from a string.....
and thus not without using the WebBrowser.
From https://stackoverflow.com/a/4935482/4546874.
However, you can hide the WebBrowser.

Opening a browser and filling in some data

i want to know how i can open a browser to a specific web page and then fill out some of the content of the boxes on that page.
My idea is for someone to be able to order a particular item from our internal ordering system. The barcodes for these items are what will populate the fields on the page i want to open.
I no i can open a new instance of ie using Process.Start("IEXPLORE.EXE", url); howver how do i get a handle on that exact ie instance window so i can begin to add the required data to the fields?
Is this even possible?
Thanks very much
WatiN should help with this. I've generally used it for acceptance testing of web apps, but the principle is the same. Open a browser instance, reference stuff in the DOM, manipulate form elements, etc.
In addition to WatiN (as was suggested in another answer), you might consider a load testing package like Web Performance Load Tester. They have a free version that lets you run up to 10 virtual users at a time, which will perform scripted actions.
Another option would be to use a standard WebBrowser object to load your website. The WebBrowser object allows you to access and alter certain web parts. Below is sample code that automatically searches Bing:
private void LoadPage()
{
WebBrowser webBrowser1 = new WebBrowser();
webBrowser1.Navigate("http://www.bing.com");
//Wait for document to load...
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
//Set the text of the search input
HtmlElement txtTextField = webBrowser1.Document.GetElementById("sb_form_q");
txtTextField.InnerText = "My test text";
//Perform a click on the search button
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("sb_form_go");
btnSubmit.InvokeMember("click");
}

Read HTML code from iframe using Webbrowser C#

How to read IFRAME html code using WebBrowser?
I have site with iframe, and after few clicks new URL opens inside this IFRAME with some portion of HTML CODE. Is there a possiblity to read this?. When I am trying to Navigate() to this URL, I am redirected to main page of this site (it is not possible to open this link twice).
Uri IFRAME_URL = webBrowser1.Document.Window.Frames[0].Url;
Maybe there is something similar to:
Uri IFRAME_URL = webBrowser1.Document.Window.Frames[0]. ... DOCUMENTTEXT;
Try:
string content = webBrowser1.Document.Window.Frames[0].WindowFrameElement.InnerText;
You can also acquire various items via mshtml types:
Set a reference to the "Microsoft HTML Object Library" under COM references.
Set your using statement:
using mshtml;
Then tap into the mshtml API to snatch the source:
HTMLFrameBase frame = yourWebBrowserControl.Document.GetElementById( "yourFrameId" ).DomElement as HTMLFrameBase;
If "frame" isn't null after that line, it has a lot of items hanging off it for your use.
try:
string content = webBrowser1.Document.Window.Frames[0].Document.Body.InnerText
A WebBrowser Control window can contain more that one iframe and .net supports frame collection so why not use something like this:
// Setup a string variable...
string html = string.Empty;
// webBrowser1.Document.Window.Frames gets a collection of iframes contained in the current document...
// HTMLWindow is the iterator for the Collection...
foreach (HtmlWindow frame in webBrowser1.Document.Window.Frames)
{
html += frame.Document.Body.OuterHtml;
}
This way, maybe with a little adjustment you can get all you need from the iframe containers you need.

c# webbrowser control displaying "special folder" contents : why are Document and DocumentDom always null?

In a C# WinForms, .NET Framework 3.5, project with a WebBrower control on the form :
... with a project reference set to MSHTMLdll and the WinForm code : "using mshtml;" ...
you can load a "special folder," like the Favorites folder, into the browser easily.
after you've loaded a "special folder" : what appears in the WebBrowser is essentially a kind of "explorer" view : you have the choice of typical "explorer" view-styles of 'Details, etc. in Details view you have a row-column matrix, with typical "Explorer" style column heads, etc.
Normally I would "get at" the DOM of the WebBrowser via casting the Document, or the DomDocument of the Document, to the IHTMLDocument2 interface exposed by mshtml.dll :
IHTMLDocument2 HTMLDocument = (IHTMLDocument2)webBrowser1.Document;
// also tried this
// IHTMLDocument2 HTMLDocument = (IHTMLDocument2)webBrowser1.Document.DomDocument;
// also tried this
// HTMLDocumentClass HTMLDocument = webBrowser1.Document.DomDocument as HTMLDocumentClass;
But in this case, viewing a "special folder" contents, I'm always getting the Document as null.
It is interesting that you can while viewing a special folder, like the Favorites, create a new folder and do other "file ops" : I wonder if I am "getting away with this" because I have protected mode turned off on IE8 ?
Appreciate any ideas about how to access the DOM while viewing special folder in the WebBrowser controls.
thanks ! Bill
The folder view isn't HTML document, so you can not use HTML interface to access the content. Use shell interfaces like IShellBrowser, IShellView and IFolderView if you are really interested in what's displayed in the window.
Typically the webbrowser's document property will be null until a page is loaded. You can try this to initialize the document property:
webBrowser1.Navigate("about:blank");
while (webBrowser1.Document.Body == null) Application.DoEvents();
// now you can access the Document property, including getting/setting the innerHtml
However, I'm not sure this will help you since the fact that the Document property is null, while you are still viewing what you want to see, suggests that even when the Document property is no longer null, that will not be the way to access the special folder data. But you can try the above code, then loading your special folder, and then looking at the document and see what you get...

Navigating to a specific fragment in a flow document from code behind

I have a WPF page used as an input form which contains a number of controls on one side, and a flow document reader on the other.
I want to set the content of this document reader to a specific part of a flow document which is loaded when the form is loaded, (via a loaded event).
I have found an article explaining how to do this, using fragments, but the examples shown are only expressed in XAML.
In my case I need to update the document property of the flow document reader when the user gives focus to one the controls (I have wired up the events already) therefore I need to do this in the code behind rather than XAML.
I have tried setting the document property to:
Document#Control_Sport
where Document is the name of XAML flow document and Control_Sport is the name of the fragment I need to navigate to.
However this gives an error, it doesn't like the hash sign being there.
I tried looking on MSDN but its XAML only. Is there a way I can do this through code?
Any help would be appreciated.
Felix,
Link to MSDN article: http://msdn.microsoft.com/en-us/library/ms750478.aspx#FragmentNavigation
You can navigate to any Block within a FlowDocument by calling Block.BringIntoView.
First, create a Frame object inside your Page or Window object. Setting the JournalOwnership property to "OwnsJournal" will give the document its own navigation bar (forward and back arrows plus a history). You will probably need to add additional parameters to size and locate the frame within your document as well, but I didn't include them in my example since I don't know what your app requires:
<Frame Name="MyFrame" JournalOwnership="OwnsJournal" />
Then, create a pack URI for your document fragment. This document is assumed to be in the same directory as the application's executable; you will need to add more to the path to navigate to the directory where the document resides in your project:
Uri MyUri = new Uri("pack://application:,,,/MyXamlDocument.xaml#MyFragment");
Then, navigate to it from inside your button's Click handler or whatever other means you like to initiate the navigation:
MyFrame.Navigate(MyUri);

Categories