Hosting WebBrowser in a Tab results in no Preview

Jan 17, 2010 at 5:43 AM

Hi,

Great control. 

I have one small problem, when I am hosting a WebBrowser control in a tab there are no screenshots of the tabitem's content.

Do you have any ideas on how this can be resolved.

Many thanks

 

Coordinator
Jan 17, 2010 at 5:39 PM

Hey tropicster,

Thanks!  Yeah, under the hood the WebBrowser control uses Win32, so the WPF visual tree can't get to it and RenderTargetBitmap won't work.  Fortunately, in another context I had to do exactly what you are trying to do.  It is possible to get a screenshot of the WebBrowser control via GDI.  You need to reference System.Drawing and then you can do something like this:

In this case "myUserControl" would be the WPF User Control that contains the WebBrowser.

Rect bounds = VisualTreeHelper.GetDescendantBounds(myUserControl);

System.Windows.Point p0 = myUserControl.PointToScreen(bounds.TopLeft);
System.Drawing.Point p1 = new System.Drawing.Point((int)p0.X, (int)p0.Y);
System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)bounds.Width, (int)bounds.Height);
System.Drawing.Graphics imgGraphics = System.Drawing.Graphics.FromImage(image);
imgGraphics.CopyFromScreen(p1.X, p1.Y, 0, 0, new System.Drawing.Size((int)bounds.Width, (int)bounds.Height));

You can then save image to a MemoryStream and stuff it into the ImageButtons on the ContentTabView or on the FabTabItem ToolTip.  So this sort of thing would go into the codebehind for ContentTabView in the FabTab source.

There are some um, "challenges" to doing it this way though.  GDI captures can show other overlapping windows, for instance a Windows Live Messenger notification that pops up and overlaps the WebBrowser, then that notification popup can sometimes be part of the screenshot.  Also, with the WebBrowser some web pages can take a while to completely load, so if the user changes the selected tab before the webpage completely renders the HTML content then the screenshot held in memory for that WebBrowser will not exactly mirror the way it looks once it's fully rendered.  So these quirks can be managed and are not showstoppers, but I thought I'd make you aware of them.

Incidentally this is a pretty specific thing you are trying to do--I don't think I will be adding a dependency on System.Drawing to FabTab or adding some of these GDI quirks to handle this case that you are dealing with.  But the beauty of open source is that you can do this yourself to the source and get the functionality. 

Please let me know how it goes.  There may be other ways besides using GDI, but as I said, I know you can get it working in that way.  Luckily almost all the changes you'd have to make would be to the one FabTab source file.

Good luck!

 

 

Mar 3, 2010 at 1:30 PM

Adding this ability to this control would be a great plus for those of us that provide our end users with tons dedicated webbrowsers in our applications.  Would it be possible to integrate this into next release?

 

Coordinator
Mar 4, 2010 at 1:21 AM

I don't think that putting GDI capabilities into this control is a great idea in terms of introducing bugs.  And to my mind WPF ItemsControl subclasses should be doing things via the WPF API, not GDI. 

That said, due to the open source nature of the product feel free to use the guidance I gave above to do so  yourself if you're so inclined. Perhaps tropicster who originally asked this question can share whether or not he's made such modifications and how well they've worked out for him. Unfortunately the HTMLBrush support that Silverlight is getting is not shared by WPF, and that would have been a good workaround that I might have incorporated into the FabTab code in lieu of having a true WPF Browser Control.

I'm guessing you need it to actually host IE, correct? If not, another possibility might be to use the WPF Chromium Web Browser control that Chris Cavanaugh has built.  More on that here: http://chriscavanagh.wordpress.com/2009/08/25/wpf-chromium-webbrowser-source-code/ and its source code is also out here on codeplex. My understanding is that because its WPF the snapshots of it should show up just fine, although I have not tried it.

The best solution of course would be for MS to pony up and make IE (and hence the browser control) into WPF.  I ran in to all kinds of problems with hosting IE in a WPF application--because its Win32 if we had WPF content that could slide out an overlay IE then IE would bleed through.  The only way around that was more unnecessary layers of interop, ie putting my overlaying WPF content inside of an ElementHost, which meant adding more winforms code.  It got very, very ugly.  It's a painful memory that I'm trying to forget ;)

If you have any other ideas on how to go about doing this besides GDI or building a WPF Browser control let me know and I'll consider them.

Best of luck!

Josh