Category Archives: XAML

xaml

Windows Phone HTML5 hybrid

Introduction

When apps for mobile devices were first introduced by the launch of the iPhone, they were written natively for the platform. As time went, more platforms entered the arena namely Android and Windows Phone. All three platforms has a fair user base. When a company or organization wants to create an app they are faced with the choice “what platforms do you want to target? What platform is used by your customers?” Often the answer to that question is that the users are spread among the three platforms and the company wants to target as many of their customers as possible.
As always there are (most often) restrictions to the projects and the biggest restriction is budget. It can be very expensive to target all the platforms with native code, especially if you build big apps like mobile web shops. Decisions must be made in how to proceed. One option is to forget about the apps and go web. That can be a good decision sometimes but not always, for instance many companies’ wants to be published and exposed via the different app stores or when the phone characteristics is needed (GPS etc.). Fortunately there is another way – Hybrid apps. The app is native but the content is built with HTML and CSS. The content is the same for the different platforms but it is hosted in a native app shell – one for each platform.
This blog post will show how you can create a hybrid app on the Windows Phone platform. As always the demo project source will be available at the bottom of the post :)

How to do it

First of all, launch your Visual Studio and then go File->new project. In the project dialog, choose the Windows Phone HTML5 App.

project selection

The project template that is created is basically an app containing a Web Browser control (IE) with navigational buttons; forward and back.


    




    
        
        
        
            
        
    

 

Take a look at the project structure. You will notice that you got one more folder than when you are creating other types of Windows Phone apps, namely the folder called Html. This is where we will put our content.
project_structure

From the start you will see that the Html folder contains an index file. This is set in code to be the file that the app will navigate to when the app starts. This is set in the code behind;

        private string MainUri = "/Html/index.html";

        private void Browser_Loaded(object sender, RoutedEventArgs e)
        {
            // Add your URL here
            Browser.Navigate(new Uri(MainUri, UriKind.Relative));
            Browser.IsScriptEnabled = true;
        }

If we inspect the index.html file we see that it is just plain html;

 
        

MY APPLICATION

page title

Try to run the app and you will get;
first_run

So far so good. We have a running app that uses an html file. We can now add as many html files as we want to create our content. Our html files work just like they would on the web, with link navigation etc. Well this will not suffice in most cases, we want to use the cool features in the phone! So our next mission is to get connectivity from the phone to the web page and back!

Send data to and from a web page

The potential for an app to send data to and from a web page is great. The cases can be for instance to send GPS-coordinates, accelerometer data and other cool sensor information. The glue between the phone and the web is our old friend, JavaScript. To enable scripting between the page and the app shell we need to do two things. First we need to set IsScriptEnabled to true on the Browser object and then we need to add an event to the Browser control that handles notifications from the web page. The event handler for this event is where all calls from the web pages will end up.

ScriptNotify="Browser_ScriptNotify_1"

The first demo we are going to implement is a GPS-tracking web page. We will use the GPS-chip in the phone and let the web page decide when the tracking is on or off. When the tracking is on, the phone will send GPS-data to the web page that will be displayed.
First step is to create the web page for our demo. We call the page gpspage.html and we place it in our html folder. Then we add some basic html to our page.


    

HTML5 hybrid demo

gps location

You are here:

We add a few rows to our css file just to emphasize on the lat, long part and when we are at it, we add css for links for our index file as well.

a {
    color:#b6ff00;
    font-size:14pt;
}

.coordinates {
    color:#b6ff00;
}

After we added the nice css we will add our JavaScript for the page. Three methods is added to the page. One for starting the GPS-tracking, one for stopping it and one for setting the location. The first two methods are calling the app-native shell and sends a string as parameter. The windows.external.notify is the method used to send data to the native part and it is the “ScriptNotify” event handler described earlier that will handle the call. The third method setLocation is a method that we will use from the native shell to set GPS-updates when they occur.

    

So now we have the interface. There are a few things left to do before we have a runnable demo. First of all, since we wants to use the GPS, we need to add that capability in the manifest file.
locationCapability

Then we will need to write some native code for the GPS to work. This is done in the MainPage.cs file. First we add a field for our GeoCoordinateWatcher and then we initialize it in the constructor of the page.

        private GeoCoordinateWatcher coordinateWatcher;
        
        public MainPage()
        {
            InitializeComponent();
            coordinateWatcher = new GeoCoordinateWatcher();
            coordinateWatcher.PositionChanged += coordinateWatcher_PositionChanged;
        }

Next thing is to add the handler for the position changed event. First we need to check to see if the page we are navigated to in the Browser has the script that we wants to access. Since we only added it to the gpspage we check to see that that is the current page. Otherwise we skip the location update. If we don’t do this, the browser will throw an exception. Note the InvokeScript method returns and object. This is good since our JavaScript methods could be implemented to return a value.

 void coordinateWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs e)
 {
      //Check to see that we only send GPS-data to our page that can handle it
      if (Browser.Source.OriginalString == "/Html/gpspage.html")
      {
         var result = Browser.InvokeScript("setLocation", new string[] { e.Position.Location.Latitude.ToString(), e.Position.Location.Longitude.ToString() });
       }
  }

Next we need to implement the start and stop. First we navigate to our method for handling notifies from the web pages and add a switch for where we are. This is to keep our code nice and tidy. And then we add a handling method for the GPS page.

        private void Browser_ScriptNotify_1(object sender, NotifyEventArgs e)
        {
            switch(((WebBrowser)sender).Source.ToString())
            {
                case "/Html/gpspage.html": ManageGPSPage(sender, e); break; 
            }
        }

        private void ManageGPSPage(object sender, NotifyEventArgs e)
        {
            if (e.Value == "startGpsTracking")
            {
                coordinateWatcher.Start();
            }
            else if (e.Value == "stopGpsTracking")
            {
                coordinateWatcher.Stop();
            }
        }

Final step before we run our app is to add a link to our index file so we can navigate to our GPS tracking page.

GPS-Demo

No we will run our app, navigate and start our tracking and it will look like this;
first run  tracking

For the fun of it and to demonstrate how easy it is to use the phone resources we are going to add another demo. This time we will use the case where you have some contact info and the desire is for the user to make a quick call from the app. First we adds a new web page to the html folder called contact.html and set it up with html and JavaScript as follows;




    
    
    
    


    

HTML5 hybrid demo

contact

Contact information

Name: John Doe

Division: Sales

Now we have html for the layout, a button for the calling and a JavaScript method that will call the native shell and provide a phone number for the contact. Next we will add the code for handling this. First stop is to extend our ScriptNotify event handler and adding a method for handling the call where we will use a PhoneCallTask for the actual phone call. If you are new to the launchers and choosers concept, please read my previous post on that topic. http://www.bjarneryd.se/?p=134

private void Browser_ScriptNotify_1(object sender, NotifyEventArgs e)
{
    switch(((WebBrowser)sender).Source.ToString())
    {
        case "/Html/gpspage.html": ManageGPSPage(sender, e); break;
        case "/Html/contact.html": ManageContactPage(sender, e); break;
    }
}

private void ManageContactPage(object sender, NotifyEventArgs e)
{
    var pct = new PhoneCallTask();
    pct.PhoneNumber = e.Value;
    pct.Show();
}

Since we are going to use the dialer we need to add the capability for that or the app will throw an exception. So navigate to the manifest and add the capability;

dialer

Finally we need to add a new link in our index file.

Contact Demo

Running the app and making a call will now look like;

mainpage contact page

prompt call phone call

Handling back behavior

So now we have created a hybrid app with two nice features that uses the native shell. The only thing is that the navigation is a bit odd. If the user tries to navigate back using the hardware button after selecting a new web page, the app will close. This is because the navigation is done in the browser and not in the app itself. This can create frustration among the users since they expect the app to navigate back. To add a feeling of being more native, you can override the default back behavior for the button. To do this, add the following method in the code behind.

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    if (Browser.CanGoBack)
    {
        Browser.GoBack();
        e.Cancel = true;
    }
    else
    {
        base.OnBackKeyPress(e);
    }
}

What we do in the code above is to see if the browser has back entries. If it does and therefore can go back, we navigate in the browser. If not, meaning we are back at the index file or we never navigated away, we will adapt the default approach and exit the app. By doing it like this we add the same navigational pattern as all native apps.

Download the source code below.

download source code

Use Prism data template selector in Windows Phone app

Quite often you would like to have a Collection in your view model that supports multiple types that derives from the same base type. Along with the different subclasses, you might want different data templates in your view, one for each type. Microsoft Prism can help you do this in an easy way and automatically select correct template for each type. This post will show how to do it on Windows Phone and you can also download the source code for the demo project (Windows Phone 7.1 for compatability) at the bottom of the page.

First of all, use Nuget to install Prism Phone to your project.
nuget prism phone

Now, lets play with an example where we want to present a Schedule that contains meetings and trips. This gives us a solution that looks like this.

We edit our simple models so they look like this;

namespace PrismTemplateSelector.Models
{
    public class ScheduleItem
    {
        public DateTime StartDate
        {
            get;
            set;
        }

        public DateTime StopDate
        {
            get;
            set;
        }
    }
}
namespace PrismTemplateSelector.Models
{
    public class Meeting : ScheduleItem
    {
        public string MeetingOrganizer
        { 
            get; 
            set; 
        }
    }
}
namespace PrismTemplateSelector.Models
{
    public class Trip : ScheduleItem
    {
        public string Destination
        {
            get;
            set;
        }
    }
}

Now we will add some code to our view model to add some demo data for our view.

namespace PrismTemplateSelector.ViewModels
{
    public class MainPageViewModel
    {
        public MainPageViewModel()
        {
            Items = new ObservableCollection();
            LoadDemoData();
        }

        public ObservableCollection Items { get; set; }

        private void LoadDemoData()
        {
            Items.Add(new Meeting()
            {
                StartDate = DateTime.Now.AddHours(1),
                StopDate = DateTime.Now.AddHours(4),
                MeetingOrganizer = "Todd Schmidt"
            });
            Items.Add(new Trip()
            {
                StartDate = DateTime.Now.AddDays(4),
                StopDate = DateTime.Now.AddDays(14),
                Destination = "New York"
            });
            Items.Add(new Meeting()
            {
                StartDate = DateTime.Now.AddDays(3),
                StopDate = DateTime.Now.AddDays(3).AddHours(1),
                MeetingOrganizer = "Gilian Pearson"
            });
        }
    }
}

Now when that is all set up, lets look at the magic in our xaml. First of all we will add namespace for Prism into our xaml-view.

xmlns:prism="clr-namespace:Microsoft.Practices.Prism.ViewModel;assembly=Microsoft.Practices.Prism"

After this we will start to write our data template and add them to our resources on the page. Note that the DataTemplate x:key shall be the name of the type you wish to bind to the template.

    
        

        
            
                
                    
                        
                            
                                
                                
                                
                            
                            
                                
                                
                            
                            
                            
                            
                            
                            
                            
                        
                    

                    
                        
                            
                                
                                
                                
                            
                            
                                
                                
                            
                            
                            
                            
                            
                            
                            
                        
                    
                
            
        

    

So finally we will tie Everything together and apply the templateselector to our listbox.


The result will now be;
prism result

download source code

Windows 8 Developer Camp

Do you want to get started developing for Windows 8, or is just curious about the what will come?
Did you miss the opportunity to go to Windows 8 Development Camps?
Then check this link out;

http://www.microsoft.com/en-us/download/details.aspx?id=29854

There you can download presentations and hands on labs from the Development Camps. Downloads are provided both for C#/XAML and for HTML/CSS/Javascript.