How to use the WebBrowser control to render custom content?
I normally blog about performance or scalability related topics. But – as I’ve been struggling with the WebBrowser control for the last couple of hours to do what I thought should be a simple task – I though it’s worth sharing my findings with you on this “functional” topic.
Scenario: Using WebBrowser control to render custom HTML and react on link clicks
I am working on a new integration of dynaTrace with Visual Studio Team System where Team System fires an event when a user changes the selection in a certain list control. My Plugin provides a control that is hosted by VSTS in a Tab and this control hosts a WebBrowser control to display content depending on the list selection. So when the user selects a new list item I am updating the data that is shown in the WebBrowser control. The generated HTML to be displayed contains links that the user can click on. The links are not real links on a WebPage but actually open a Dialog or send requests via a WebService interface.
My list of requirements therefore were
- Display HTML content based on selected list item
- Handle Link Click on my own instead of WebBrowser control trying to follow the link
Following image shows the control in action – nicely hosted by VSTS in a separate Tab:
I quickly figured out to
- use the DocumentText property to set my custom HTML code
- register a callback via HTMLDocumentEvents2::onClick
- prevent link clicks from being followed by the control by setting AllowNavigation to FALSE
Everything worked fine with my first generated HTML page. Trouble started when I tried to set a new value to DocumentText. Although setting a new HTML text – the control seemed to dismiss my change. It turned out that I had to set AllowNavigation to TRUE in order to set a new text. It seems that internally the browser control is browsing to a new HTML page which was prevented. AllowNavigation is of course not what I wanted as I wanted to prevent link clicks to be followed by the WebBrowser control. Changing the property to TRUE just for the task to change the DocumentText property didn’t do the trick either. Seems that – once you prevent navigation you cannot change DocumentText.
Solution
After lots of different attempts and lots of blogs that I browsed I came up with the ultimate solution. Using the Navigating and Navigated events I was able to prevent the WebBrowser control from navigating to links that have been clicked but allowing the control to browse to the new HTML that I set via DocumentText.
Here is my code:
private bool allowNavigate = false;
public WebResultForDynaTrace()
{
InitializeComponent();
webBrowser.Navigating += new WebBrowserNavigatingEventHandler(webBrowser_Navigating); webBrowser.Navigated += new WebBrowserNavigatedEventHandler(webBrowser_Navigated); }
void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
allowNavigate = false;
}
void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (allowNavigate) return;
e.Cancel = true;
// check which link was clicked and do my own actions
if(e.Url.ToString().StartsWith("myAction1"))
doAction1();
}
public void SetNewHTMLContent(string htmlContent)
{
allowNavigate = true;
webBrowser.DocumentText = htmlContent;
}
Conclusion
The WebBrowser control offers a great way to integrate HTML in your Rich Client Application. There are many managed and also unmanaged COM interfaces that you can use to interact with the control. I just found that some property changes impact the controls behavior in a way that I didn’t expect. I hope this blog entry helps you to avoid those long hours that I spent to figure this out.
Related posts:
- SharePoint: Identifying memory problems introduced by custom code SharePoint is a great platform that makes it easy to...
- How to analyze and speed up content rich web sites likes www.utah.travel in minutes One of my daily activities is checking interesting blog posts...























No comment yet