0

I'm trying to capture the content of a WebBrowser control that is not in the visible tree, but the WriteableBitmap.Render() is capturing a (correctly sized) bitmap of all black pixels. If I put the WebBrowser into the visual tree, the capture works fine.

WriteableBitmap doc is emphatic that it works on controls not in the visual tree, and I'm making the required calls to Measure() and Arrange(). Relevant code (originally in WebBrowser_LoadCompleted event, for demo moved to renderButton_OnClick)

        hiddenBrowser.Measure(new Size(hiddenBrowser.Width, hiddenBrowser.Height));                // pretend there's plenty of space.
        hiddenBrowser.Arrange(new Rect(0.0, 0.0, hiddenBrowser.Width, hiddenBrowser.Height));     // pretend we know where this is going.
        //noHelp hiddenBrowser.UpdateLayout(); 

        WriteableBitmap _bitmap = new WriteableBitmap((int)theImage.Width, (int)theImage.Height);
        _bitmap.Render(hiddenBrowser, new ScaleTransform());
        _bitmap.Invalidate();
        theImage.Source = _bitmap;

A complete project demonstrating the problem is available at: https://skydrive.live.com/redir?resid=193BF22F5BBA1A84!10526&authkey=!AGeH6YC_NttOmj0

Press Unhide (webBrowser shows in visual tree), then Go, then Render --> render captures OK. Then press Hide (webBrowser disappears), then Go, then Render --> Black Screen of Ignorance.

Originally, I thought this was a timing issue (e.g maybe browser hadn't finished painting the web page even though LoadComplete event fired), but it cannot be; in the demo, I wait for 10s of seconds before pressing 'render' button which does the render, and still get black image.

BobHy
  • 1,575
  • 10
  • 23

2 Answers2

0

I reproduced your problem. It seems like the Control isn't rendered if not necessary.
Do you really need the WebBrowser to be in the Visual Tree?
If you just want it to be invisible, setting the Visibility to Collapsed won't work either (I tried).

An ugly trick that works for the WebBrowser to be invisible to the user but still allows a WriteableBitmap rendering is to translate the control out of the ViewPort. To do that, just use a TranslateTransform:

hiddenBrowser = new WebBrowser();
hiddenBrowser.Width = theImage.Width;
hiddenBrowser.Height = theImage.Height;
hiddenBrowser.LoadCompleted += hiddenBrowser_LoadCompleted;
hiddenBrowser.NavigationFailed += hiddenBrowser_NavigationFailed;
hiddenBrowser.LayoutUpdated += hiddenBrowser_LayoutUpdated;
hiddenBrowser.RenderTransform = new TranslateTransform { X = 2000, Y = 2000 }; // this is the code I added.

Ugly but working solution!

Olivier Payen
  • 15,198
  • 7
  • 41
  • 70
  • No, I do not need or want the WebBrowser to be in the visual tree. My goal is to be able to run the WebBrowser and capture its image on a background thread. I appreciate your interesting hack, but I don't think that will work in the background, either. I'm going to give it a try, though. – BobHy Sep 12 '13 at 23:21
  • @BobHy, if you all you need is to capture a WebBrowser image on a background thread, check this [answer](http://stackoverflow.com/a/18675926/1768303). – noseratio Sep 13 '13 at 01:46
  • 1
    @Noseratio, sorry, WP8 WebBrowser control doesn't have .WriteToBitmap() method. – BobHy Sep 13 '13 at 16:45
0

This turns out to have been doomed from the start.

You can't run the WebBrowser control in the background on WP8, period. It's an Unsupported API. And, as noted above, there's the issue (maybe not a bug?) that WebBrowser won't provide a bitmap when it's not in the visual tree, anyway.

BobHy
  • 1,575
  • 10
  • 23