Jaime Rodriguez
On Windows Store apps, Windows Phone, HTML and XAML

  • Jaime Rodriguez

    Back button press when using webbrowser control in WP7

    • 3 Comments

    If you have a Windows Phone application that hosts the WebBrowser control and allows or encourages the users to navigate within the WebBrowser control’s space,  you are going to run into the 5.2.4.b certification requirement:

                    “Pressing the Back button must return the application to the previous page”

    This requirement is easy to understand for PhoneApplicationPages; but for HTML, I am still undecided on how intuitive it would be to a user that is navigating inside a WebBrowser control. 
    Most of the apps I have been involved with that use the WebBrowser control, do not encourage navigation ( they show small HTML inline) or show HTML it in a popup that only has a close button on the top right, so I have never worried about integration between WebBrowser and back button.  It was always a “Back” closes the transient popup.
    That said, I saw a news reader  app last week that had a full screen WebBrowser, and a back and forward button in the appbar, this felt weird ( to see a back button in the appbar) I thought the hardware back button should integrate with this “perceived” navigation stack .  This got me thinking about 1) how hard it is to code and 2) how error prone it would be.

    Yesterday, I quickly threw in an HTML page that I felt would cover most linking scenarios. It has regular navigations (A HREF) , shortened URLs (that lead to redirects), navigates using script, and has fragment navigations.   I then created a project with WebBrowser to integrate with back button.

    Here is my one-hour exploration:

    1) Listen to WebBrowser.Navigated event;  keep track of the pages that have been visited.

    Stack<Uri> history= new Stack<Uri>();
    Uri current = null; 
    private void WebBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    {
        Uri previous = null;           
        if (history.Count > 0)
            previous = history.Peek();
    
        // This assumption is NOT always right. 
        // if the page had a forward reference that creates a loop (e.g. A->B->A ), 
    //
    we would not detect it, we assume it is an A -> B -> back () if (e.Uri == previous) { history.Pop(); } else { if (current != null) history.Push(current); }
    current = e.Uri; } 2) Listen to OnBackKeyPress on the page. If the WebBrowser has a navigation stack, cancel the backkeypress and navigate within the webbrowser control’s stack.
    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
    {
        base.OnBackKeyPress(e);
    
        if (!isPerformingCloseOperation) 
        {
            if (history.Count > 0)
            {                        
                    Uri destination = history.Peek();
                    webBrowser.Navigate(destination);
                    // What about using script and going history.back? 
                    // you can do it, but 
    //
    I rather use that to keep ‘track’ consistently with our stack e.Cancel = true; } } }

    As you can see, code is trivial, but it has an issue I did not solve.  I can’t tell the difference between:

    1. Navigate(a) –> Navigate ( b) –> back ();
    2. Navigate(a) –> Navigate ( b) –> Navigate ( a ) ;

    I tried letting the browser do the work, and peeking at history.length (you can see the code in the sample, commented out), but that does not help since the sequence #1 above leads to a length of 2, instead of a length of 0.    Since that does not solve it (and I don’t see a different way, is this good enough?   I think it is, because:

    • I believe scenario #2 above does not happen a lot. So, I optimized for #1, it does the trick because worst case it gets user out quicker.
    • If you are concern on #2, you can add an ‘escape valve’.  I put a close button on the top right hand of the page, so the user can close the browser page if they want to; you could also use appbar if your page has one.

    Unless I missed another major gotcha, I think this does nicely.   It is intuitive to the user in most typical navigations. It lets them out of the browser page (history.length was getting stuck since it never decreased to 0).    I also asked internally to the Microsoft folks building apps, and the ones that integrate back button and webbrowser navigation are using the same pattern, and have not had any complaints from users. 

    To conclude, here is my personal advise/summary:

    • Not all apps need this integration. If you are just showing a single page, and don’t want to encourage navigation, use a UX pattern that hints the user that the UI is transient – make it look like a popup, put a close button on the popup’
    • If you have an app that does encourage navigation in the browser,  consider the pattern above. Don’t do it because of the certification requirement, do it because it is intuitive to the user. That is why the requirement exists. 
    • If you feel that your app does not fall under one of the above, then do ask for an exception to the certification team. That said, I emphasize you should thrive to create an intuitive experience for your user. I think the two options do that best so I recommend them –as opposed to the excuse/exception route-.

    Sample code is here.

    Happy Windows Phone coding!

    If you want to keep up with Windows Phone on a more frequent basis, subscribe to my Windows Phone question of the day RSS feed.

  • Jaime Rodriguez

    An update from Windows Phone developers themselves

    • 3 Comments

    The past few days have been very exciting for Windows Phone developers:

    I am very excited about the roadmap, but I am also jazzed about our success to date, so I thought I would let developers in the marketplace tell you about their successes today.

    Two weeks ago, a few developers participating in LG’s hAPPiness program were here in Redmond and I was invited to join them for an hour of “tips and tricks.”
    [Sideline, the hAPPiness program is a great offer that allows LG phone owners to download and keep 10 great free apps from their marketplace. It is a wonderful promotion for apps, and as a value-add to LG phone owners, apps will rotate over time, so you will be able to pick from far more than the original twenty selected to-date].

    I was able to meet most of the developers, and was impressed with their excitement, passion, and eagerness to write new apps or improve their current ones. It was so cool that I asked if I could record them to show to our internal platform teams, who always get a rise out of seeing cool apps and hearing from developers.

    Here are my personal conclusions from meeting the group1:

    • Developers are making good money! None of them are retiring tomorrow or ordering a Ferrari (yet), but the money is adding up nicely. Even free applications with ads are making money. You don’t have to take only my word for this; check out this article from Inside Mobile Apps for download comparisons between Android and Windows Phone.2
    • Developers are having a lot of fun! The platform is easy to use and it is very RAD, the tools are free, we have great phones that users love, and a growing user base--not a bad playground for developers.
    • The Silverlight and Windows Phone community rocks. I don’t get to say this often, so I will use this chance to shout out to the Insiders, MVPs, early adopting partners, and all the other community folks who are on the forums, sharing their stories and their feedback (both good and bad)3.

    Those were my conclusions; but you don’t take my word for it. Take time to watch the interviews  below.  
    [Disclaimer: We were focused on the developer’s stories. Though they all demo their apps, the crappy recording (me), the room (improvised), and our goal of keeping the chat to just a few minutes, did not do the apps justice.
    Check out the apps in the marketplace links below, and don’t forget, if you are an LG user, these are free for a limited time.

    • Balint Orosz is one of the folks from Cocktail Flow. You can watch his interview here.
      In just a month he created a very successful app leveraging the skills he had (.NET, Silverlight); he might take it to other platforms now that the concept is vetted and much better funded.
      My summary from his story:“It is OK to get started on Windows Phone, leverage your skills if you are .NET or Silverlight developer”.
    • Emad Ibrahim is the creator of  Envision, Notesly+, QuoteZen, Picasa Viewer (and possibly others since he codes faster than I blog). You can watch his interview here.
      Emad is super fast at creating apps, and is getting great ROI from his apps.  My take away on his story: “Get started now, while the competition is low.”
    • Andy Beaulieu (creator of Talking Rag Doll) and Jeff Weber creator of Krashlander.  You can watch their video here.
      Jeff is one of the original creators of the open source farseer physics engine on codeplex . Andy was the first person to wrap it in Blend, contributing some cool Blend behaviors for it. 
      I thought it was great to see community contributors meet and finally get financial benefits from their community efforts.  They seem happy that other developers are cashing and using their library/behaviors. My take away for their video, have fun!!
      [Sideline,
      according to Inside Mobile Apps, KrashLander has had 15,900 $.99 downloads in January]

    Thanks to all of the devs for playing along on such short notice and letting me share their recordings. Check out their apps--and good luck creating your own!

    Foot-notes:

    1 I have to emphasize these are my personal conclusions. Don’t over-generalize it to my employer or folks in the Windows Phone team.
    2 I don’t want to spin the numbers and compare to Android (you can ignore that part or not, your call). I only refer to the article because they have independent numbers on how well apps some are selling.
    3 Again, the platform and phone have been rock-solid. The area where we have been less than stellar is the marketplace. I can assure you that the right people are listening; there have been a huge number of improvements, and there are more on the way. There are 8,000+ apps in the marketplace, so clearly it ain’t all broken; be persistent and keep pushing us. I will come back to the marketplace topic in a future post (hold me to this).

     

  • Jaime Rodriguez

    Communication between HTML in WebBrowser and Silverlight app

    • 0 Comments


    Two people asked on this post about communication between HTML and Silverlight, so I thought I would share broadly about the more 'advanced' techniques. 
    [Don't be misled, advanced is still easy, just explaining all you can do].

    Silverlight on Windows Phone allows you to host HTML content in a WebBrowser control. You get bi-directional communication between the control and the HTML content:

    • For HTML to host comunication, the WebBrowser control injects script into the page, and your javascript can call window.external.notify (<param>) to communicate with Silverlight.
      There is nothing you need to do (like include a js file). You just call the function in HTML and  calling it will trigger the WebBrowser.ScriptNotify event on the Silverlight side.

     

    • For host to HTML, webbrowser control calls the WebBrowser.InvokeScript method, passing a string with the function name, and an array of string params ).

    If you own the HTML page you are hosting, the infrastructure above is all you need to get anything done (since you can just add the javascript to communicate). 
    If you don’t own the page you are calling things are slightly more interesting but still very doable – these are the scenarios that fuel this post –.
    These are the communication mechanisms I use when talking to HTML on a page that comes from a server that I can’t control or influence.

    1. Use the execScript javascript function to call arbitrary javascript. execScript does not return a value, but you can call methods that don’t need to return one, for example:
      webBrowser.InvokeScript("execScript", "history.go(-1)"); 
    2. Use the eval javascript function to call arbitray javascript, and return a value from that javascript.  The return must be a string, but you can easily solve it by doing a toString() on any type (or using JSON if you need to return some thing complex).  For example:
      // this will fail, it returns null 
      // object height = webBrowser.InvokeScript ( "eval", "document.body.offsetHeight" );  
      // this works
      string height = (string) webBrowser.InvokeScript ( "eval", "document.body.offsetHeight.toString()" );
    3. You can even take these techniques to the next level and inject scripts into the DOM, listen for events, and call back to your host. All of this without owning the page you are hosting.
      For example: this snippet below is C# on the host WebBrowser control that inserts a function into the DOM, and then wires a listener for the click on a button in the page,  the event handler that we are wiring up  calls window.external.notify  () to let our host know the event was clicked.  Without owning the page, we can listen to events in the HTML. What more can we ask for?
      Here is the code:

      StringBuilder bldr = new StringBuilder();
      bldr.Append("var script = document.createElement('script');");
      bldr.Append("script.text = 'function cb () { "); 
      bldr.Append("window.external.notify (\"this text was injected on the fly\");}';");
      bldr.Append("var headNode = document.getElementsByTagName('HEAD'); "); 
      bldr.Append( "if (headNode[0] != null);headNode[0].appendChild(script); ;");
      bldr.Append("var element= document.getElementById('btn'); "); 
      bldr.Append("if ( element != null ) element.onclick = cb;");
      webBrowser.InvokeScript("execScript", bldr.ToString());


    I am sure there are more techniques, but the combination of the 3 above has gotten me pretty far in communicating between JS and Silverlight.

    If you want to see the code above in action, download this sample.

    Happy Windows Phone coding!

    If you want to keep up with Windows Phone on a more frequent basis, subscribe to my Windows Phone question of the day RSS feed.

  • Jaime Rodriguez

    FAQ about copy paste functionality in upcoming release

    • 0 Comments


    I received a few questions about this post, and the nodo bits that were released last week, some of the answers are worth sharing broadly.

    About the UI guideline comment
    [this is the one worth the clarification]

    What is the UI guideline about not using TextBox in pivot/pano?  Where is it documented?
    This is mostly a recommendation (similar to keeping panorama UIs simple and clean).

    It is not a formal guideline since it varies by app layout/scenario.  As you know, panoramas and pivots do  listen for touch gestures, and the guidelines have always said you should avoid controls that fight for touch (such as sliders, map, etc.);  a textbox is a bit more dependent on the scenario: copy/paste is not the primary function of a textbox; it should come down to what the textbox does; if the app is filling a form and you have lots of textboxes, then I too would avoid putting them inside a panorama or pivot.  On the other hand, if you have a scenario that mostly presents data and really shines in a panorama or a pivot but you need a textbox that fits well into the scenario (such as a search box), it should be OK to use.  The new controls mitigate touch conflict a little, and as long as you position your textbox and the usage is appropriate, my early preview testing says it is OK.  

    Will my app fail if I have a textbox in a pano?
    Again, no. This is not a requirement.

    What you should know and maybe act/upon:

    My app does not have a pivot/panorama.  Do I need to recompile and resubmit?
    For the most part, you should not have to resubmit (if you don’t have textbox inside pivot/pano).  The exception are people that were manipulating TextBox’s focus and selection.  If you manipulate these, it is safe to test to make sure it all works.

    if I don’t recompile, will I get copy/paste in my app?
    Yes. Without recompile and resubmit, your app will get copy/paste in updated phones, and the performance improvements will also be there.
     
    Will I get the performance improvements?
    Yes, these are also coming for free.

    Details on the API
    Can I get programmatic access to the clipboard?
    Not in this release.

    Can I disable copy/paste?
    No. That would be awkward to the user.

    What controls get copy/paste?
    TextBox, PasswordBox.  WebBrowser control includes support c/p too (if you have textboxes in the HTML).
    TextBlock does not get it, but you can re-template a TextBox to look like a TextBlock  (do make sure to set it read-only).

    Will new features be added to the API in future releases (e.g. programmatic access or clipboard access)?
    Of course.  This current update is mostly an OS release, that is why the Copy/Paste is not very platform focused; but expect improvements in future platform releases.

     

    Of course I have also heard the question:
    When does the release go live?  Unfortunately, I don’t know the exact date (and I am bad at guessing). You can leverage the developer tools today and recompile your app with the new pivot/pano and submit to the marketplace any time. You do not have to wait for the release.  Don’t wait until date is announced and end up fighting the certification queues.

Page 1 of 1 (4 items)