Adventures with the Windows Phone 7 WebBrowser Control


I have been spending some time recently working with the Windows Phone 7 development tools and thought I’d start blogging more about writing applications for the forthcoming Windows Phone 7 platform.

I was asked a question this morning about how you might display content, embedded within the application assembly, using the WebBrowser control for Windows Phone 7.

We’ll start by creating a new Windows Phone Application within Visual Studio 2010 and then we’ll add the WebBrowser control to the main page, resizing the control to expand it into the available space on the page.

WebBrowserAdventures

All Windows Phone 7 controls derive from the FrameworkElement class, which provides the Loaded event which occurs when the FrameworkElement has been constructed and added to the object’s tree.

Let’s add a small html page to the project and then, within the file properties for the html page, set the Build Action to “Embedded Resource”.

<html>
    <body>Windows Phone 7 Rocks!!!</body>
</html>

If we attempt to load Html into the browser, using the WebBrowser controls NavigateToString method before the browser control is in the visual tree, an InvalidOperationException will be thrown advising us that “You cannot call WebBrowser methods until it is in the visual tree.” We’ll therefore add the following code within the event handler for the WebBrowser controls Loaded event.

Assembly assembly = Assembly.GetExecutingAssembly();

using (Stream stream = assembly.GetManifestResourceStream("WebBrowserAdventures.EmbeddedResource.html"))
{
    using (StreamReader reader = new StreamReader(stream))
    {
        string html = reader.ReadToEnd();

        webBrowser1.NavigateToString(html);
    }
}

We’ll use the GetManifestResourceStream method to load the embedded html page from the application assembly and then the StreamReader class enables us to read the content of the html file into a string. With the html contained within the string, the NavigateToString method will enable us to render the html in the browser.

Using the Windows Phone 7 emulator we can see the html from the embedded resource displayed within the WebBrowser control.

EmbeddedHtml

While displaying embedded content within the WebBrowser control is very useful it is of course primarily intended to display content from the Web and doing so is as easy as assigning a value to a single property. Within the WebBrowser control, the Source property allows us to assign an instance of the Uri class representing the Uri of the content we’d like to display.

Displaying the Bing site on Windows Phone 7, using the WebBrowser control is as easy as:

webBrowser1.Source = new Uri("http://www.bing.com");

WebBrowserSource

We announced on Monday that the final build of the Windows Phone 7 developer tools will be available on September 16th with the marketplace going live sometime in early October. You can read more about the roadmap to Windows Phone 7 launch and the availability of the final tools here.

I encourage you to take download the tools and start writing a game or application, be part of the Windows Phone 7 experience! 

Comments (17)

  1. Mark Wager-Smith says:

    Thanks Doug.  This is really great.  I'm really getting excited about the Windows Phone 7 and the ease with which I can create applications for it.  I'm going to download the developer tools soon and get started!

  2. Doug Holland says:

    Hey Mark,

    That's great to hear that you'll get started with the tools soon!

    I think you'll find the developer experience is something that we've paid very close attention to with Windows Phone 7 and that end users are going to absolutely love the devices running Windows Phone 7 when they launch later this year.

    Let me know if you have any questions about Windows Phone 7 once you have started building an application or game!

    Thanks,

    – Doug

  3. Eric says:

    Doug, from what I can tell there is no way to specify the encoding that the WebBrowser control uses when  populating it with NavigateToString(). How are we supposed to deal with extended character sets using this control?

  4. Roro says:

    this is cool. my question:

    is it possible to insert script into the html resource? i tried to insert something like the below but nothing was rendered, if it is possible, do you have an example? what would i need to do in that case. thanks in advance.

    <html>

    <head></head>

    <body>

       <div style="font-size:3.0em;">

           <script type="text/javascript" language="JavaScript" src="http://www.fabricom.com/ast.pl

       </div>

    </body>

    </html>

  5. Ronan says:

    thanks for the article. one question:

    i tried including javascript in my html resource page. such like: script language=javascript and src="uri.."

    but my page didn't display anything. is the browser control supports such embedded script or this is not supported for security reasons? the thing is that if i use the same script in desktop IE, it will work just fine. thanks much

  6. Sebastian says:

    thank you mark!

    unfortunately, images or extern stylesheets in src- and href-attributes in the html-file are not displayed.

    what can i do?

    thanks,

    sebastian

  7. Doug Holland says:

    Hey Roro, Ronan,

    With respect to running JavaScript within the browser ensure that the IsScriptEnabled property is set to true.

    Regards,

    Doug

  8. Janak says:

    Can I pass the Object Reference of my application to a Script insided the HTM Document? Like what we have ObjectForScripting in full framework? If not is there any way to do it?

  9. Doug Holland says:

    Hey Janak,

    You are right that the ObjectForScripting property doesn't exist in the Windows Phone 7 WebBowser class. I have asked internally about how you might go this and will add another comment when I hear although my own research hasn't yielded any potential ways to do what you're looking to do.

    Regards,

    Doug

  10. Janak says:

    Thanks Doug for your prompt reply.

    I did very much Research on this but couldn't found any solution. Let me know if you get any breakthrough on this.

    Regards,

    Janak

  11. Doug Holland says:

    I was just advised that given that this properly is used to expose COM objects methods / properties to scripting in a Web Browser control; and since COM objects are not supported by WP7, you really would not use this.

    For communication between the client and the web browser control you can use the WebBrowser.InvokeScript command. For example:

    private void webBrowser1_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)

    {

       // dump the raw cookie string from the currently loaded web page

       string[] codeString1 = { "document.cookie;" };

       object o = webBrowser1.InvokeScript("eval", codeString1);

       Debug.WriteLine(o);

       // Dump URL user loaded

       Debug.WriteLine(e.Uri.ToString());

    }

  12. Janak says:

    Thanks dohollan for your reply.

    My requirement is to navigate the screen through script and for the same I may need to pass the reference of the class which is responsible for screen navigation to a script. I know in full silverlight framework this support is available but I'm worrying to support it for windows phone 7.

  13. Newbie Kim says:

    Hi Sirs, I tried this but I recieve ArgumentNullException for stream in this line

    StreamReader reader = new StreamReader(stream))

    Here's my .cs file and my html file is test.html which  has Build Action to Embedded Resource already. I think it doesn't read test.html. this is already located in the same project folder, though. thanks for the help, guys!

    namespace EmbedShell3

    {

       public partial class MainPage : PhoneApplicationPage

       {

           // Constructor

           public MainPage()

           {

               InitializeComponent();

               webBrowser1.Loaded += new RoutedEventHandler(webBrowser1_Loaded);

           }

           public void webBrowser1_Loaded(object sender, RoutedEventArgs e)

           {

               Assembly assembly = Assembly.GetExecutingAssembly();

               using (Stream stream = assembly.GetManifestResourceStream("test.html"))

               {

                   using (StreamReader reader = new StreamReader(stream))

                   {

                       string html = reader.ReadToEnd();

                       webBrowser1.NavigateToString(html);

                   }

               }            

           }

       }

    }

    Kim

  14. Kim says:

    Hi Sirs, I tried this but I recieve ArgumentNullException for stream in this line

    StreamReader reader = new StreamReader(stream))

    Here's my .cs file and my html file is test.html which  has Build Action to Embedded Resource already. I think it doesn't read test.html. this is already located in the same project folder, though. thanks for the help, guys!

    namespace EmbedShell3

    {

       public partial class MainPage : PhoneApplicationPage

       {

           // Constructor

           public MainPage()

           {

               InitializeComponent();

               webBrowser1.Loaded += new RoutedEventHandler(webBrowser1_Loaded);

           }

           public void webBrowser1_Loaded(object sender, RoutedEventArgs e)

           {

               Assembly assembly = Assembly.GetExecutingAssembly();

               using (Stream stream = assembly.GetManifestResourceStream("test.html"))

               {

                   using (StreamReader reader = new StreamReader(stream))

                   {

                       string html = reader.ReadToEnd();

                       webBrowser1.NavigateToString(html);

                   }

               }            

           }

       }

    }

    Kim

  15. Sathish says:

    Hi Janak and Doug,

    I have a similar requirement to call a C# method from the Javascript in a Html page loaded in WebBrowser control. Could you share solution or work around, if any you got?

    Thanks.

    Rgds, Sathish  

  16. Janak says:

    The only thing I've found is to throw window notify message from script that would be handled by applcation and parse the string to execute from application.

    It is like call the script using invokescript, do some manipulation, notify the window application, execute C# code, return result to script.

    No oher solution found so far…

    We'll have to wait for Windows Phone 7.5.

  17. Ashok Solanki says:

    HI,

    I have a problem with web browser control, it is not support Turkish word.

    Please help me.

    Thanks in advance.