Tuesday, October 16, 2012

Windows Store Apps quick tip: the sneaky selected item in CollectionViewSource

When assigning an ItemsSource there is a fundamental difference in CollectionViewSource vs “standard” collections: Using a CollectionViewSource will mark the first item as selected, using a “standard” collection will not.

Imagine if you will a ListView where you handle SelectionChanged and fetch data from somewhere depending on what item is selected. If you’re using a CollectionViewSource and navigate to the page you’ll fire that call twice – first for the default selected item, then for the passed in parameter that you’re likely using to the set SelectedItem.

That is all.

Windows Store Apps quick tip: getting the app version number

If you need to get the version information of your app from code, the details you want resides in Windows.ApplicationModel.Package.Current.Id.Version.

For example, to get a full version string you could use the below code:

string.Format("{0}.{1}.{2}.{3}", Windows.ApplicationModel.Package.Current.Id.Version.Major, 
                                 Windows.ApplicationModel.Package.Current.Id.Version.Minor, 
                                 Windows.ApplicationModel.Package.Current.Id.Version.Build, 
                                 Windows.ApplicationModel.Package.Current.Id.Version.Revision)

That is all.

Wednesday, October 10, 2012

Windows Store Apps – a generic connectivity-dropped control to take that worry from your brow

(If you can’t be bothered reading the text and just want the code it’s available for download here)

One of the requirements when publishing your Windows Store app is that the app needs to handle connectivity loss. No matter how much you curse at the certification requirements that one is there for a good reason (as many of them are), and it prevents the user experience from going haywire. So, it’s fair game, not much you can say about that. Usually what people do here is add a handler to the Application.UnhandledException event and swallow as many/few of the exceptions they can. Good on you. now your app is fool-proof.. or is it?

What about letting your user know something happened visually? well, you could show a MessageDialog with the details of that error. I suppose that, at least, gives a bit of context.

Back to connectivity. This shouldn’t be a concern. This houldn’t steal time from you that you can spend on implementing all your ideas. This should just be handled.
One way to handle these issues automagically is by creating a generic control that can visually present meaningful (hopefully, but up to you) context to your user while the app has lost connectivity.

Therefore, I give you ConnectivityPopUp.

ConnectivityPopUp is a custom control that pops up an overlay across the entire screen when your app looses connectivity. The guts of the control consists of a PopUp control containing a Grid with a FlipView and FlipViewIndicator (from the awesome Callisto framework), along with some dependency properties and a control template.

Once placed on your page it handles the hassle of connectivity for you – all you have to do is supply it with at least one ConnectivityPopUpPage and place the control on your page(s). Behind the scenes it then attaches to the Windows.Networking.Connectivity.NetworkInformation.NetworkStatusChanged event.

            var connectivityPages = new ObservableCollection<Usoniandream.WindowsStore.Controls.ConnectivityPopUpPage>()
                                        {
                                            new ConnectivityPopUpPage(){Title = "have you tried DiceFeud yet?", 
                                                                        _imagePath = "Assets/MediumGray.png", 
                                                                        Description = "Lorem ipsum … ante"}
                                        };
            this.DefaultViewModel["ConnectivityPages"] = connectivityPages;

Once that event is fired, and handled, it takes care of telling the UI to show the control on the appropriate thread. This is accomplished simply by travelling the action of setting IsOpen=true through Dispatcher.RunAsync().

The default layout of the control is fairly minimalistic and, yes, boring.

        <usoniandream:ConnectivityPopUp
            Pages="{Binding ConnectivityPages}" />

image

 

But it doesn’t have to be boring. You can customize it using BackgroundImagePath and BackgroundImageStretch properties to your liking.

Perhaps you instead want to create a Homer Simpson styled one..?

        <usoniandream:ConnectivityPopUp
            BackgroundImagePath="Assets/ohno.png" 
            BackgroundImageStretch="Uniform" 
            Pages="{Binding ConnectivityPages}" />

image

 

Or maybe HAL resides somewhere in the void of space in your app..?

        <usoniandream:ConnectivityPopUp
            BackgroundImagePath="Assets/space.png" 
            BackgroundImageStretch="UniformToFill" 
            Pages="{Binding ConnectivityPages}" />

image

The control is dependent on Tim Heuer’s Callisto framework since it uses the FlipViewIndicator from that framework.

This is just my take on handling connectivity issues in a generic way.

If it suits your needs – go grab it. Then use it.
If it doesn’t – go grab it anyway. Then turn it inside out. Change it. Invert it.

Monday, October 08, 2012

Windows Store Apps – a Panorama-ish GridView

The idea is simple: Take a GridView, tweak it to see if it’s possible to get a somewhat similar feeling as the Panorama control for Windows Phone.

If you search for panorama and windows store you’ll likely end up in discussions about something called “parallax background” – at least that’s what I did. One article that cought my eye was this one written by John Michael Hauck. He took an interesting approach and created a ParallaxConverter to sort it all out. Cudos to him – that’s the one I’m using in this example.

Also included in this marriage-of-a-lot-of-techniques is the tip from Jerry Nixon on how to use a variablesizedwrapgrid and custom gridview to make it a little prettier found here.

So, quick recap of the recipie for this sweet cake:

  1. Implement “panorama-ish” effect thanks to John Michael Hauck.
  2. Make the item layout a bit nicer thanks to Jerry Nixon.
  3. Bake both together for 20 minutes
  4. Ready to serve hot from the oven

I won’t dig into details of the code in this post, you have the sourcecode available for that if you wish to dive in.

If you observe the images below you’ll see that the background moves much slower than the gridview in the foreground – voila! mission accomplished!

imageimageimageimage

This is an experimental, playful and far from perfect code. It’s just here to show you that it can be done, and that there are techniques out there that can help you a lot.

Feel free to grab the code in this zip archive. Use or modify it as you wish. If you got the balls to give credit where credit is deserved, go thank Jerry Nixon, John Michael Hauck and the other authors in the community for the effort they put into sharing what they know.

Tuesday, September 18, 2012

Windows Store Apps – using a generic service layer

Another perhaps helpful tip when building Windows Store Apps that are connected in some way to the internet: You can easily create a reusable “service layer” for your web requests that make consuming async http urls more of a walk in the park.

With that said, say hello to the GenericServiceLayer for Windows Store Apps.

the idea is simple: extract away as much as possible from the (often) repetitive task of sending web requests in a windows store app.

Usage:

  1. Reference the dll/project
  2. In your viewmodel/datasource/whatever, create a GenericServiceLayer
  3. use it in your code

Setting up a GenericServiceLayer in your code shouldn’t take much more than this:

    public class GenericServiceLayerSample
    {
        private GenericServiceLayer service = null;

        public GenericServiceLayerSample()
        {
            CookieContainer cookieContainer = new CookieContainer();
            HttpMessageHandler handler = new HttpClientHandler() { CookieContainer = cookieContainer, UseCookies = true};
            handler = new InspectorHandler(handler);
            var client = new HttpClient(handler) { BaseAddress = new System.Uri("http://dev.virtualearth.net/REST/v1/Locations/") };

            service = new GenericServiceLayer(client);
        }
    }

Note that the code above also uses the InspectorHandler I wrote about in the previous post.

Now, to use it. It’s really as simple as:

        public async void Sample()
        {
            // get a string response
            var response = await service.GetAsync("Eiffel%20Tower?o=json&key=BingMapsKey");
            // get a Json.NET mapped model
            var responseModel = await service.GetAsync<MyEiffelTowerModel>("Eiffel%20Tower?o=json&key=BingMapsKey");
        }

Passing in parameters/content is done in a structured way using the normal syntax, for example:

            // pass in content via PUT and get a string response
            HttpContent content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("SomeInnerContent", "innercontent")
            });
            var response = service.PutAsync("Eiffel%20Tower?o=json&key=BingMapsKey", content);

The methods (GET, POST, PUT) exposed in the GenericServiceLayer all implement IAsyncOperationWithProgress<Tresult, int> which easily enables you to also report progress on the requests made:

            // get a string response and listen for progress
            var response = service.GetAsync("Eiffel%20Tower?o=json&key=BingMapsKey");
            int reportedProgress = 0;
            response.Progress = (info, progress) =>
            {
                reportedProgress = progress;
            };

The above “reportedProgress” would probably be a property in your viewmodel (or the approach you’re running with that makes use of NotifyPropertyChanged) so that it’d present a visual progress notification in your app when changed.

Perhaps you’ll find this useful, it has proven valuable in the adventures of Windows Store Apps I’m currently embarking on.

Full source code can be downloaded here.

Windows Store Apps – a simple HttpClient request & response debugger

Here’s the deal: Debugging is a pain. Sometimes a huge pain, other times it’s not that big of a deal. Regardless of the case at hand I often find myself digging into the requests and responses of the HttpClient, so therefore I wrote this little helper.
So, with that said, let me introduce you to InspectorHandler for Windows Store apps.
It’s simple really - InspectorHandler is a MessageProcessingHandler that you can add to your HttpClient definition that outputs the request & response from the HttpClient to the debug output window when you’re in debug configuration.
Usage is really straight forward:
  1. Hook up the handler
  2. Create the HttpClient
  3. You’re set.
Continue using the HttpClient just as you normally would with await, ReadAsStringAsync() and all that.
        private async void btnGo_Click_1(object sender, RoutedEventArgs e)
        {
            // declare http handler
            HttpMessageHandler handler = new HttpClientHandler();
            // append the Inspector handler
            handler = new InspectorHandler(handler);
            // allocate a http client on the above handlers
            var client = new HttpClient(handler) { BaseAddress = new System.Uri("http://dev.virtualearth.net/REST/v1/Locations/") };

            // fire request
            var response = await client.GetAsync("Eiffel%20Tower?o=xml&key=BingMapsKey"); // insert a proper bing maps key here otherwise you'll just get the access denied view..
            // output result
            tbContent.Text = await response.Content.ReadAsStringAsync();
        }
      Below is a screenshot of a example app that once the button is pressed fires a GET request to the http://dev.virtualearth.net/REST/v1/Locations/Eiffel%20Tower?o=xml&key=BingMapsKey url and ouputs the result into a textbox.
image  
And some basic interesting details from the request & response objects are now available in the ouput of the debugger:
image  
There you have it. Simple, fairly effective and perhaps useful. Under the hood the InspectorHandler is far from a work of art, but it does the job quite well for being a simple debug tool. Here’s the complete source code:
    public class InspectorHandler : MessageProcessingHandler
    {
        public InspectorHandler(HttpMessageHandler innerHandler)
            : base(innerHandler)
        {
        }

        protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken)
        {
#if DEBUG
            if (request.Content!=null)
            {
                var content = request.Content.ReadAsStringAsync();
                content.Wait();
                Debug.WriteLine(string.Format("INSPECTOR: {0} REQUEST - {1} - {2}", request.Method, request.RequestUri.ToString(), content.Result));
            }
            else
            {
                Debug.WriteLine(string.Format("INSPECTOR: {0} REQUEST - {1}", request.Method, request.RequestUri.ToString()));
            }
#endif
            return request;
        }

        protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken)
        {
#if DEBUG
            if (response.Content!=null)
            {
                var content = response.Content.ReadAsStringAsync();
                content.Wait();
                Debug.WriteLine(string.Format("INSPECTOR: {0} RESPONSE - {1} - {2}", response.RequestMessage.Method, response.StatusCode, content.Result));
            }
            else
            {
                Debug.WriteLine(string.Format("INSPECTOR: {0} RESPONSE - {1} - {2}", response.RequestMessage.Method, response.StatusCode));
            }
#endif
            return response;
        }
    }
If you want it, you can grab it here as a zip containing the class library project ready to be compiled & referenced.

Sunday, June 10, 2012

LocationServices for Windows Phone updates

Things change fast at times, and today is such a time.

  • Eniro has entered the arena as a datasource
  • ServiceLayers are completely removed
  • Caching is updated
  • Models are now partial classes
  • Reverted to using RestSharp 102.7 (including added JSON.NET again)

More posts on this will follow, but for now the biggest change is the move from ServiceLayers to actually executing the criteria itself by attaching .Execute()

            var rxbing = new Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Bing.Translation(
                "sv", 
                "en", 
                "en-US", 
                "badplatser", 
                "parklek", 
                "samhälle")
                .Execute()
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(bing);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        bing.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });

full source code, sample app and binaries: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

Friday, May 18, 2012

LocationServices for Windows Phone: Bing Translation made simple

Hello again. To be honest, a translation API is not in any way a location-aware API (unless you can send in coordinates and get the target language), but it is a tremendously useful API none the less and a lot of solutions could benefit from having one.

For that reason I’ve implemented Bing Translation in the LocationServices for Windows Phone framework.

Usage is exactly like the rest of the framework: you specify a criteria (in this case a Translation criteria) and then you fire that at the service and out you get an observable Translation (or a collection of that, depending on how you use it).

translation

In the screenshot above I’ve sent the Swedish words “badplatser”, “lekpark”, “samhälle”, “polis” & “källkod” for translation to it’s English equivalent.

The implementation is created in such a way that you can add several words (or phrases for that matter) to the criteria and it will only fire one shot at the service, instead of one per word/phrase.

Enough talk, let’s code.

References

These are the bare minimum references needed.

  • RestSharp
    • local build of RestSharp 103.1 with a tiny change. Located in the lib folder.
  • Reactive Extensions
    • NuGet: Rx_Experimental-Xaml
  • LocationServices for WIndows Phone
    • Usoniandream.WindowsPhone.LocationServices
    • Usoniandream.WindowsPhone.LocationServices.Bing

ViewModel code

in short: an ObservableCollection for the result, a ServiceLayer and a method that wires the translation.

    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation> translations;
        public ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation> Translations
        {
            get
            {
                if (translations == null)
                    translations = new ObservableCollection<Usoniandream.WindowsPhone.LocationServices.Models.Bing.Translation>();
                return translations;
            }
            set
            {
                translations = value;
            }
        }

        public Usoniandream.WindowsPhone.LocationServices.Service.Bing.Reactive.ServiceLayer serviceLayer { get; set; }

        public MainViewModel()
        {
            serviceLayer = new Usoniandream.WindowsPhone.LocationServices.Service.Bing.Reactive.ServiceLayer();
        }

        public void WireBingTranslation()
        {
            IsDataLoading = true;
            Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Bing.Translation criteria = new Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Bing.Translation("sv", "en", "en-US", "badplatser", "lekpark", "samhälle", "polis", "källkod");
            var rxbing = serviceLayer.Translate(criteria)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        Translations.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });
        }
        public bool IsDataLoading { get; set; }
    }

XAML code

I’ve left out everything from the view except this tiny ListBox implementation ‘cause it really is the only interesting part.

            <ListBox ItemsSource="{Binding Translations}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Margin="12,0" Text="{Binding From}" Style="{StaticResource PhoneTextNormalStyle}" />
                            <TextBlock Margin="12,0" Text="translates to" Style="{StaticResource PhoneTextSubtleStyle}" />
                            <TextBlock Margin="12,0,12,24" Text="{Binding To}" Style="{StaticResource PhoneTextNormalStyle}" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

And, as shown above, that gives us:

translation

Wrapping up

That sample code is available here for download, just remember that you need a Bing AppID of your own and set that in the App.xaml. If you don't already have an AppID, you can sign up and get it at http://www.bing.com/developers/appids.aspx.

Now, for anyone using the other parts of the framework you also have the option of sending any model that implements ILocation in the criteria instead of strings. Doing so will translate the Content property of that object. In a future version you’ll get the sent in object back translated, but for now you’ll just have to do with the content as a Translation.

The framework libraries, source code and sample app are all on GitHub: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

Tuesday, May 15, 2012

LocationServices for Windows Phone: now with caching support!

I’ve added a simple caching container for the framework, enabling you to cache the results from a criteria.

Simply set the CacheProvider property on the service to a cache provider that implements ICacheProvider from the framework, then configure the caching in the CacheSettings property of the criteria.

Consider the following Instagram criteria search:

        public Service.Instagram.Reactive.ServiceLayer instagramservicelayer { get; private set; }

        public MainViewModel()
        {
            this.instagramservicelayer = new Service.Instagram.Reactive.ServiceLayer();
        }

        private void WireInstagramPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem instagram = new GenericPivotItem() { Header = "photos", Source = "instagram" };
            SearchCriterias.Instagram.MediaByLocation criteria = new SearchCriterias.Instagram.MediaByLocation(new GeoCoordinate(40.74917, -73.98529));
            
            var rxinstagram = instagramservicelayer.GetMediaByLocation(criteria)
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(instagram);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        instagram.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });
        }

Now, to add caching to that you simply add a provider to the service and specify caching on the criteria:

        public MainViewModel()
        {
            this.instagramservicelayer = new Service.Instagram.Reactive.ServiceLayer() 
            { 
                CacheProvider = new LocationServices.Caching.IsoStoreCache.IsolatedStorageCacheProvider() 
            };
        }

        public Service.Instagram.Reactive.ServiceLayer instagramservicelayer { get; private set; }

        private void WireInstagramPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem instagram = new GenericPivotItem() { Header = "photos", Source = "instagram" };
            SearchCriterias.Instagram.MediaByLocation criteria = new SearchCriterias.Instagram.MediaByLocation(new GeoCoordinate(40.74917, -73.98529))
                {
                    CacheSettings = new SearchCriterias.CriteriaCacheSettings(60 * 60 * 24)
                };
 
            var rxinstagram = instagramservicelayer.GetMediaByLocation(criteria)
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(instagram);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        instagram.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });

        }

In the code above the cache duration (specified in the CacheSettings) is the number of seconds the cached item(s) should be considered valid, here 60*60*24 = 24 hours.

You can of course create your own cache provider - simply implement the ICacheProvider interface and it’s methods in your own provider class. You’ll find the interface in the Caching namespace in the Usoniandream.WindowsPhone.LocationServices library.

The framework libraries, source code and sample app are all on GitHub: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

Sunday, May 13, 2012

Introducing Stockholm Explorer for Windows Phone

This post will be a bit weird, it’s written in English but it’s actually all about a Swedish app I’ve just published.

As of today Stockholm Explorer for Windows Phone is available on the marketplace: http://www.windowsphone.com/sv-SE/apps/270e2242-e160-4f05-b70e-b216705349e9

This app is a POI (Point Of Interest) finder/explorer for the city of Stockholm and it’s surroundings - built entirely using the LocationServices for Windows Phone framework.

PeterDrougge_None_FX_2012-05-05_09-56-46

The app utilizes the framework to combine and present data from Stockholm, Nokia Places, Twitter, FLickr, Commute Greener and Instagram. And it does so brilliantly ;)

If you’re Swedish (sorry – at the moment the app is in Swedish only, this however I’m planning on changing in the next version) and either living in Stockholm or happen to be/going there I hope you’ll find it useful.

The app has been developed using frameworks such as Reactive Extensions, RestSharp, Silverlight for Windows Phone Toolkit and LocationServices for Windows Phone.

Download: http://www.windowsphone.com/sv-SE/apps/270e2242-e160-4f05-b70e-b216705349e9

Thursday, May 10, 2012

LocationServices for Windows Phone: getting media from Instagram based on location

Just a few minutes ago I pushed updates to the Instagram part of the framework, here’s a quick example of getting media based on a location:

        public MainViewModel()
        {
            this.instagramservicelayer = new Service.Instagram.Reactive.ServiceLayer();
        }

        private ObservableCollection<GenericPivotItem> pivotItems;
        public ObservableCollection<GenericPivotItem> PivotItems { get { if (pivotItems == null) pivotItems = new ObservableCollection<GenericPivotItem>(); return pivotItems; } set { pivotItems = value; } }

        public Service.Instagram.Reactive.ServiceLayer instagramservicelayer { get; private set; }

        private void WireInstagramPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem instagram = new GenericPivotItem() { Header = "photos", Source = "instagram" };
            var rxinstagram = instagramservicelayer.GetMediaByLocation(new Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Instagram.MediaByLocation(new GeoCoordinate(40.74917, -73.98529)))
                .Take(20)
                .ObserveOnDispatcher()
                .Finally(() =>
                {
                    PivotItems.Add(instagram);
                    IsDataLoading = false;
                })
                .Subscribe(
                // result
                    x =>
                    {
                        instagram.Items.Add(x);
                    },
                // exception
                    ex =>
                    {
                        MessageBox.Show(ex.Message);
                    });

        }

with the result as seen below (don’t pay attention to the lack of design):

instagram

NOTE: the project currenty holds a local version of the RestSharp dll located in the lib folder. This is due to the fact that the JsonDeserializer in RestSharp was throwing InvalidCastExceptions when parsing certain types of json result. I’ve updated the JsonDeserializer in this local version.

The framework libraries, source code and sample app are all on GitHub: http://peterdrougge.github.com/Usoniandream.WIndowsPhone.LocationServices/

LocationServices for Windows Phone: Added Google Places and Instagram

Last night I added data libraries for Google Places and Instagram.

SearchCriterias available for Google Places:

  • PlacesByRadius
  • PlaceDetails
  • EventDetails

SearchCriterias available for Instagram:

  • PlacesByLocation
  • MediaByLocation
  • MediaDetails

At the moment they won’t fly since the mappers for each library is not completed – something I’m going to push very shortly and then they’re ready to use.

Windows Phone development: RestSharp and JSON response without a root object

Not everyone thinks alike, and not everyone builds the same.

RestSharp is, in lack of better words, freakin’ awesome. It rocks when it comes to Windows Phone web requests. There’s one little thing you should look out for though, and that’s the structure of the JSON response.

Basically, there’s two types: the root response type where the response has a root object that holds the response, and the rootless response type where the response lacks a root object and instead returns a collection of items at this point.

Parsing the first one is a piece of cake with RestSharp, all you have to do is something like

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

and you’re set. It automagically deserializes the json response to your model.

But.. (there’s always that “but”). If the object is rootless you might need to append a little extra at the beginning and end of the response prior to it being deserialized.

In this case all you have to do is make use of the OnBeforeDeserialization handler of the Request object.

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");
            request.OnBeforeDeserialization = response => {response.Content = string.Format("{0}{1}{2}", prefix, response.Content, suffix)};

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

where “prefix” and “suffix” in the above code is the wrapper you need to make a root object surrounding the original response.

You can place it as a method instead if you want:

        private void AddPaddingToResponse(IRestResponse response)
        {
            response.Content = string.Format("{0}{1}{2}", "{\"features\":", response.Content, "}");

And use that for OnBeforeDeserialization (this is approach is more friendly for debugging purposes, the other is just a bit more cool and inline):

            RestSharp.IRestClient client = new RestSharp.RestClient("http://MyBaseUrlThatIsNotRealButOnlyAnExample.com");
            RestSharp.IRestRequest request = new RestSharp.RestRequest("MyResource/Example/IsAlso/NotReal");
            request.OnBeforeDeserialization = AddPaddingToResponse;

            var asyncHandle = client.ExecuteAsync<MySampleObject>(request, response =>
            {
                // got the response..
            });

And finally, a little sidenote: remember that you can Cancel the request if you want. Nice feature that helps with responsiveness of your app and is easily implemented by overriding the Back button event and simply calling:

            asyncHandle.Abort();

That’s it, and that’s that.

LocationServices for Windows Phone: drop it like it’s hot

As of today the dependency to JSON.NET is no longer required and therefore it has been removed. This was made possible by upgrading RestSharp to version 103.1.

There might be a few Json deserialization issues to take care of in the near future, but the majority of them should be fine since I’ve tested quite a lot of them already.

The framework libraries, source code and sample app are all on GitHub: https://github.com/peterdrougge/Usoniandream.WIndowsPhone.LocationServices

Monday, May 07, 2012

Windows Phone development: an alternative to zooming all your map locations into view

When you’re using the Maps control to layout your items it’s always nice if you give the user the possibility to zoom/scale to show all items, this however can be a pain. While I’ve seen a few different approaches to solving this, like diving deep into projection/delta and more I thought I’d share a different (and a lot easier) approach.

Often it’s sufficient enough to just create a LocationRect based on the current GeoCoordinates and add a little “padding” to it, then call the SetView method of the map with that LocationRect.

Here’s a sample:

image

in the image above we’re fairly zoomed down to a level where a lot of items are simply out of view. That helicopter button in the application bar does the following when clicked:

            // simple collection later used for the LocationRect..
            List<GeoCoordinate> coords = new List<GeoCoordinate>();

            // add current location (yeah, we wanna be in the picture as well)
            coords.Add(viewModel.CurrentLocation);
            
            // transform any location-aware item collections into simple GeoCoordinate lists, then add that to the coords list..
            if (this.mapServiceUnits.Visibility == System.Windows.Visibility.Visible)
                coords.AddRange(viewModel.ServiceUnits.Select<Usoniandream.WindowsPhone.LocationServices.Models.Stockholm.Base.IServiceUnit, GeoCoordinate>(x => x.Location));
            if (this.mapNokiaPlaces.Visibility == System.Windows.Visibility.Visible)
                coords.AddRange(viewModel.NokiaPlaces.Select<Usoniandream.WindowsPhone.LocationServices.Models.Nokia.Places.Place, GeoCoordinate>(x => x.Location));
            
            // finally, use the GetLocationRect with a little "padding" to nicely fit the items in view. (mapLocations is the name of the map control in this example)
            mapLocations.SetView(MapExtensions.GetLocationRect(coords, 0.003));

and that leaves us with a map zooming out nicely to show all the items:

image

How was that accomplished? Basically all you need is the GetLocationRect extension method included in the code below:

//
// Copyright (c) 2012 Peter Drougge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
using Microsoft.Phone.Controls.Maps;
using System.Device.Location;
using System.Collections.Generic;

namespace Usoniandream.WindowsPhone.Extensions
{
    public static class MapExtensions
    {
        public static LocationRect GetLocationRect(IEnumerable<GeoCoordinate> coords, double padding)
        {
            LocationRect rect = LocationRect.CreateLocationRect(coords);
            if (padding>0)
            {
                rect.West -= padding;
                rect.East += padding;
                rect.North += padding;
                rect.South -= padding;
            }
            return rect;
        }
    }
}

now, just to clarify I’m gonna show those images next to each other so you’ll see the difference:

imageimage

It might not be the most elegant solution, nor the most mathematically correct, but if you just want to make sure your items (at least the actual locations of them) are in view, well then I’m confident that little piece of code will suffice.

Saturday, May 05, 2012

LocationServices for Windows Phone: example of an application using parts of the framework

My second wild creation is waiting certification approval at the moment, that however hasn’t stopped me from completing the next version of it: Stockholm Explorer v1.1.

The original v1.0 version combines POI information from the city of Stockholm and Nokia Places, giving easy access to addresses, phone numbers etc. But that’s about it. While waiting for the approval of it I decided to add some more functionality, and thus the addition of Twitter, Flickr & CommuteGreener to the framework.

In the new 1.1 version not only will you get information such as phone numbers, opening hours, addresses etc, but you’ll also get Flickr photos from the vicinity of the location, as well as nearby tweets and a Co2 emission calculation based on different forms of transport to reach the location.

Consider this screenshot a sneak preview of the next version of Stockholm Explorer for Windows Phone that will be available.. well.. soon after the 1.0 version is made available.

PeterDrougge_None_FX_2012-05-05_09-56-46

LocationServices framework parts used:

  • Usoniandream.WindowsPhone.LocationServices.Stockholm
  • Usoniandream.WindowsPhone.LocationServices.Nokia
  • Usoniandream.WindowsPhone.LocationServices.Twitter
  • Usoniandream.WindowsPhone.LocationServices.Flickr
  • Usoniandream.WindowsPhone.LocationServices.Commute

The framework libraries, source code and sample app are all on GitHub: https://github.com/peterdrougge/Usoniandream.WIndowsPhone.LocationServices

Thursday, May 03, 2012

Windows Phone development: Improving the startup time and responsiveness of your application

I’m sure you all know the certification rule of how long your app is allowed to load (if not, here’s a big tip: go read the certification requirements and guides – it’ll save you a lot of time later on). Now, assuming you’re familiar with that rule I won’t cover it any further, nor will I cover the how & why of the below, I’m just going to leave you with one more option to improve startup time instead of just transferring load to the Loaded event..

Here’s what you really should avoid

Fetching data in the constructor is never a good idea.

    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // here you really shouldn't be loading anything since the first frame hasn't fired yet, but let's assume that you did..
            ViewModel.RunMyDataFetchingStuff();
        }
    }

And here’s how you normally avoid the above

Deferring load to the Loaded event of the page let’s the app fire the first rendered frame.

    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            // transfer loading to only run after the first frame..
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // aaaaaand here we load some data..
            ViewModel.RunMyDataFetchingStuff(); 
        }
    }

If you still experience delays here’s an extension to the above alternative

If you think there’s still room for improvement when it comes to loading your views, try using a timer to further defer the load past the regular Loaded event.

    public partial class MainPage : PhoneApplicationPage
    {
        DispatcherTimer firstTimer = new DispatcherTimer();

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // hook up timer..
            firstTimer.Interval = TimeSpan.FromMilliseconds(500);
            firstTimer.Tick += new EventHandler(firstTimer_Tick);
            // transfer loading to only run after the first frame..
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // and off we go - tick, tick, tick, tick, boom!
            firstTimer.Start();
        }
        void firstTimer_Tick(object sender, EventArgs e)
        {
            firstTimer.Stop(); 
            // aaaaaand here we instead load some data, ‘cause here we really should be clear of any initial freeze..
            ViewModel.RunMyDataFetchingStuff(); 
        }
    }

Performance issues can be a pain for any developer to tackle, but also for the end user. Try to focus on the experience you initially set out to create, then attack each issue one at a time. There’s plenty of patterns, tutorials and guidance out there in case you need help. As a start you can look here, here, here, here or here.

Needless to say the above won’t act as a cleaver on your startup time, but it might help.

Windows Phone development–applying a custom style to change the visual presentation of a radiobutton

Fact: the Metro principles are great and the controls we have available renders with grace and simplicity.

Regardless of all that, there are times when we just want the functionality of a radiobutton list, but the appearance of something completely different. This is where retemplating or applying styles come into play and really makes xaml shine.

in the following example we’re going to turn this..

image

.. into this..

image

.. by simply applying a custom style.

so, from the top then, we have a group of radiobuttons..

    <RadioButton x:Name="rbCar" GroupName="one" IsChecked="True">
        Car
    </RadioButton>
    <RadioButton x:Name="rbBike" GroupName="one">
        Motorcycle
    </RadioButton>
    <RadioButton x:Name="rbTruck" GroupName="one">
        Truck
    </RadioButton>
    <RadioButton x:Name="rbWheelchair" GroupName="one">
        Wheelchair
    </RadioButton>

now, we’ll addew n a custom style called “AVeryDifferentRadioButton”..

        <Style x:Key="AVeryDifferentRadioButton" BasedOn="{StaticResource PhoneRadioButtonCheckBoxBase}" TargetType="RadioButton">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RadioButton">
                        <Grid Background="Transparent">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver"/>
                                    <VisualState x:Name="Pressed" />
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentGrid">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="CheckStates">
                                    <VisualState x:Name="Checked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentGrid">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unchecked">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentGrid">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneSubtleBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid x:Name="ContentGrid" Margin="{StaticResource PhoneTouchTargetLargeOverhang}" Width="80">
                                <ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" 
                                                x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" 
                                                Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" 
                                                FontFamily="{TemplateBinding FontFamily}" Margin="0" Padding="{TemplateBinding Padding}" />
                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

and we’ll use that style and also change the contents to images..

    <RadioButton x:Name="rbCar" GroupName="one" IsChecked="True">
        <Image Source="/Content/images/car.png" />
    </RadioButton>
    <RadioButton x:Name="rbBike" GroupName="one">
        <Image Source="/Content/images/bike.png" />
    </RadioButton>
    <RadioButton x:Name="rbTruck" GroupName="one">
        <Image Source="/Content/images/truck.png" />
    </RadioButton>
    <RadioButton x:Name="rbWheelchair" GroupName="one">
        <Image Source="/Content/images/wheelchairpng" />
    </RadioButton>

and that is it:

image

Now it renders in quite differently while still giving us the functionality of a traditional radiobutton.

LocationServices for Windows Phone update: added Twitter

I’ve added Twitter as a new data layer library with a search criteria to SearchByRadius. Using this search will return all tweets with a valid geo location (either by the Geo attribute, or by a string parse of the Location attribute) within the set radius from the specified location (GeoCoordinate).

twitter

Usage example

        public MainViewModel()
        {
            this.twitterrservicelayer = new Service.Twitter.Reactive.ServiceLayer();
        }
        private ObservableCollection<GenericPivotItem> pivotItems;
        public ObservableCollection<GenericPivotItem> PivotItems { get { if (pivotItems == null) pivotItems = new ObservableCollection<GenericPivotItem>(); return pivotItems; } set { pivotItems = value; } }
        public Service.Twitter.Reactive.ServiceLayer twitterrservicelayer { get; private set; }

        private void WireTwitterPivotItem()
        {
            IsDataLoading = true;
            GenericPivotItem tweets = new GenericPivotItem() { Header = "tweets", Source = "twitter" };

            var rxtweets = twitterrservicelayer.GetTweetsByRadius(new Usoniandream.WindowsPhone.LocationServices.SearchCriterias.Twitter.SearchByRadius(new GeoCoordinate(40.74917, -73.98529), 0.5))
           .Take(20)
           .ObserveOnDispatcher()
           .Finally(() =>
           {
               PivotItems.Add(tweets);
               IsDataLoading = false;
           })
           .Subscribe(
                // result
               x =>
               {
                   tweets.Items.Add(x);
               },
                // exception
               ex =>
               {
                   // handle exception..
               });
        }

Current framework contents (as of 2012-05-03)

Core libraries:

  • Usoniandream.WindowsPhone.Extensions
  • Usoniandream.WindowsPhone.GeoConverter
  • Usoniandream.WindowsPhone.LocationServices

Data libraries:

  • Usoniandream.WindowsPhone.LocationServices.Bing
  • Usoniandream.WindowsPhone.LocationServices.Commute
  • Usoniandream.WindowsPhone.LocationServices.Flickr 
  • Usoniandream.WindowsPhone.LocationServices.Goteborg
  • Usoniandream.WindowsPhone.LocationServices.Nokia
  • Usoniandream.WindowsPhone.LocationServices.Orebro 
  • Usoniandream.WindowsPhone.LocationServices.Stockholm
  • Usoniandream.WindowsPhone.LocationServices.Stockholm.AR
  • Usoniandream.WindowsPhone.LocationServices.Twitter

The framework libraries, source code and sample app are all on GitHub: https://github.com/peterdrougge/Usoniandream.WIndowsPhone.LocationServices