wp7dev: Using WebBrowser as an alternative to overcome multi-line TextBlock size limitation by Chris Ismael

*UPDATED: Generated html using NavigateToString instead of hosting on server. Actually I could’ve just generated everything in HTML instead using that*

Those of you who have been playing with the TextBlock control on WP7 and requiring tons of text to be written out are probably familiar with the limitation where your text is truncated beyond 2048×2048 pixels

There’s this cool solution where this dude created a custom Scrollable TextBlock for WP7 that addresses this by calculating the number of lines you have to display and automatically generating several TextBlocks in a StackPanel. However during my testing, this implementation consumes too much memory (90MB at one instance on the phone emulator).  My scenario calls for displaying the underlying source code of a web page on my app on WP7.  As you can imagine, there could be tons of javascript functions and css declarations under the hood. 

image

The Trick

What I ended up doing was to use a WebBrowser control in WP7 to display the text instead. You can check out my app here.  Also check out the snapshot below on how this looks like in action.

image

There are two things that this app does. First is to pull the underlying source code of whatever url page you place on the text box.  Second is to display that source code “text” for the user to see.  We will only focus on the second part for this post.

How to Set It Up

Perhaps one of the most underrated marvels of Silverlight is its ability to “talk” to  HTML, and vice versa.  You can read about it here and here (“Calling Javascript Functions in Windows Phone 7”).  I suggest you read them first before proceeding.

1. WebBrowser control

Here’s what the UI layout looks like from VS2010:

image

The WebBrowser control is the one with the IE logo, and the xaml declaration for that looks like this:

image

What’s interesting here is that you need to set “IsScriptEnabled” to True to allow bi-directional communication with the HTML page.  If you don’t set this, no magic happens.

2. Hook up the browser events and call the javascript functions

image

image

Here we are doing two things – hook up to the browser control’s Navigated event and ScriptNotify event.  The Navigated event is optional.  We are only using it in this case so that we have a cue to make the browser control appear (note that it is set to Visibility=”Collapsed” in the xaml declaration above).  We hide it initially to show the instructional text behind it (“Paste URL above and press…”).

image

The ScriptNotify event gets called from javascript in the HTML (which we will see later).  We hooked up the ScriptNotify event to give us our cue to start passing data to the browser control; we don’t want to send data until the browser page has properly loaded.  This part is HTML calling Silverlight.

What’s interesting here is the InvokeScript method inside, to which we pass the name of the javascript function to call, and the data we’re passing.  Note that at this point, “textToBeDisplayed” already holds the text we want to display.  This part is Silverlight calling HTML.

3. HTML and the javascript functions

Below are the html source code and the javascript functions we need to set up. The “DataReceivedFromPhoneApp” javascript function below is the one that gets called from the C# code to pass the text we want to display.  This updates the div element to display the text.  The “SendDataToPhoneApp” gets called on body’s onLoad event.  It has a window.external.notify function which calls back to Silverlight.  This is the cue for the app to start sending text.

image

Do note that you need to host this on a server somewhere.  You will then point to this html page from your C# code to start the process.

Fire it up

Once all these are in place, you can now call generate the html page from your C# code. 

image

Going back to what we have set up above, the following chain of events will happen when we load this html page by calling the function above (once we have the text to pass for that page to display):

1. The HTML page loads and the onLoad event kicks in, to call the SendDataToPhone javascript function. (HTML –> Silverlight)

2. The C# event handler for ScriptNotify gets called as a result, which then calls the javascript function on the html page, passing along the text to display. (Silverlight –> HTML)

3. The javascript function manipulates the div element to insert the text to be displayed.

In summary

This solution works well for my case.  The only convoluted part is that I need to host an html page on a server, so it is not a self-contained solution (versus the TextBlock solution).  You need to take that into account if you are using this type of solution.  The bonus I get with this kind of solution is that I can zoom in and out as you would in a browser control on WP7.  That is good for inspecting a very long html source code on a small screen device such as WP7.  (Why anyone would do that could be a subject of another topic Smile with tongue out )

Happy coding!

Related Posts

Leave a Reply