Friday, October 24, 2008

Display html Content in WPF (XBAP)

Story of displaying html content in WPF or XBAP (WPF browser application) begins with a simple requirement, we have to show printer friendly version(which is a html content) on few reports in our project that run on Internet and which is a WPF browser application. Well it is a quite simple requirement and most of the application needs such kind of printer friendly version that run on web. There are several techniques or solutions to this problem we are going to take a look each of a kind in short.

WPF Frame Element

First of all we are going to see a simple solution to this problem. WPF have an element called Frame element. Frame element is used to display wpf  page and user control. We can also use a frame element to show our html contents. User need to set the source property of the "Frame" to Uri of the Html Page. Here is a simple code example that shows how to do that.

<Grid Height="300" Width="479">
<Frame x:Name="myframe" Source="C:\TabotGenerator\TestXbap\HTMLPage1.htm"></Frame>
</Grid>



Few things must need to take in concern before using frame wpf frame or other elements don't support uri other than the site of origin in partial trust mode. so report handler html or aspx or custom handler must be in the site of origin. And while navigating the source must be marked as a Absolute Uri using the "UriKind" Enum.



Open a new Browser Window



Second solution to show html page in wpf is to use a navigation window object of wpf. Its kind of a mini browser where any wpf page or any resource that is viewable can be loaded. The following code snippet will show how to use a navigation window to show html page.





NavigationWindow window = new NavigationWindow();
Uri source = new Uri("http://mydomain/myapp/report.aspx", UriKind.Absolute);
window.Source = source;window.Show();




In the same category we can also use Hyperlink to Popup more traditional kind of browser window, that is popup a IE browser window just like traditional printer friendly version on sites. but to lunch a new browser window target name property must be set to _blank or some thing like that. bellow code snippet is given. Note that hyperlink element is created inside a label. WPF is by designed like this. hyperlink must be inside text elements for example label and text block.





<Label>
<Hyperlink TargetName="_blank" NavigateUri="http://mydomain/myapp/report.aspx"></Hyperlink>
</Label>




3.5 SP1 Web Browser Control



Microsoft dot net framework 3.5 Service pack one is equipped with a new control type called web browser control. Web browser control is a very smart control supporting navigation to normal Uri source and also displays html content dynamically. User can set its source property to display html page which is traditional way just like two above mentions technique. Web browser control also support three life saving methods.





Uri source = new Uri("http://mydomain/myapp/report.aspx", UriKind.Absolute);
WebBrowser browser = new WebBrowser();
this.Content = browser;browser.Navigate(source);
browser.NavigateToStream(new FileStream("Pathofthehtmlfile",FileMode.OpenOrCreate));
browser.NavigateToString("<html> whole html content </html>");




 



Among the above mention methods “NavigateToString” is very usefull in case we need to display html content which is available to us as a string data. And we don’t have to use any printer friendly handler page on the source of origin site in this case. We can retrieve our printer friendly html content using a string content and then just use NavigateToString to display the conent. We can also use template html to generate html content for printer friendly version.



Using Windows Forms Web Browser control



In case we are not using dot net framework 3.5 sp1 we can still implement the technique to display html content directly in browser without having a ASPX handler page in the site of origin of the XBAP. We are going to use a legacy browser control of window forms. Window forms have a built-in browser control from the release of Microsoft .net framework 2. We can also use this control using this legacy browser control via windows forms host control of WPF.




<Grid Height="300" Width="479"><WindowsFormsHost Name="windowsFormsHost1" /></Grid>



 




System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser();
windowsFormsHost1.Child = browser;
//do assign the html content directly
browser.DocumentText = "our html string";
//or do assign the uri of the html page
Uri source = new Uri("http://mydomain/myapp/report.aspx", UriKind.Absolute);
browser.Navigate(source);




Conclusion



Using the above solution one thing must be kept in mind that any time you can encounter with the system.net.permission error or perhaps partial security violation error. for this you need to modify your code in such a way so that you can get the best out of it. In my case I will use the new 3.5 sp1 browser control. I will retrieve the html content via some web service or WCF service and then assign the string to web browser using navigate to string method. Best of luck and happy programming.