Jaime Rodriguez On Windows Phone, Windows Presentation Foundation, Silverlight and Windows 7
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:
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.
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).
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.
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.
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:
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.
webBrowser.InvokeScript("execScript", "history.go(-1)");
// 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()" );
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.
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:
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:
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:
Sample code is here.