XAML Playground
about XAML and other Amenities

WP8: A utility class to call choosers using async/await

2013-10-18T15:50:55+01:00 by Andrea Boschin

The relatively recent introduction of async/await keywords in C# has been an important news to help people solve theri problems with the intrisic asynchronous programming model tha comes from the roots of Silverlight. As I often pointed, the asynchronous model is much more effective, but it usually makes the code hard to be wrote and to be understood. with the async/await keywords, all the hard work is done under the hoods by the compiler but there are still a number of cases where these keywords are not directly applicable. One of these is the call of Choosers in Windows Phone 8, where we do not have the needed handles to use this tecnique but we still need to rely on a "Completed" event handler. Let me say that the goal of this post is to avoid the following code:

   1: public void ChoosePhoto()
   2: {
   3:     PhotoChooserTask pct = new PhotoChooserTask();
   4:     pct.ShowCamera = true;
   5:     pct.Completed += HandlePhotoChooseCompleted;
   6:     pct.Show();
   7: }
   8:  
   9: private void HandlePhotoChooseCompleted(object sender, PhotoResult e)
  10: {
  11:     // do what you want with choosen photo
  12: }

Getting the result in a separate method make the code hard to be understand and, in this case, also does not correctly unhook the eventhandler causing additional work for the garbage collection. A complete and effective solution should be much more complex and require the use of member fields in a class. The desire of every progremmer is to call the same this way:

   1: var photo = await DeviceServices.ChoosePhoto(true);

After some tryies I'm able to create the DeviceServices class and inside of it I've created a single method that is able to call every chooser, not only the PhotoChooserTask. Please remember that this applies to the Choosers only, because Launchers does not have a common base class and, actually, the do not require a similar approach since they do not returns any result.

As a careful investigation, a chooser is made of two classes working together: The "chooser" that is a class derived from ChooserBase<T> and a "result" that may be a TaskEventArgs or a class derived from it. So we can declare the following method and be sure it apply to every existing chooser:

   1: private static Task<K> InvokeChooser<T, K>(Action<T> initCallback = null)
   2:     where K : TaskEventArgs
   3:     where T : ChooserBase<K>, new()
   4: {
   5:     // launch chooser here
   6: }

These two classes exposes all the required handles to create, run and retrieve the result from the chooser. The sole problem is in the options specific for the chooser. For this purpose the initCallback method is invoked with the instance of the chooser to let the caller set the options. Here is the full body of the method:

   1: private static Task<K> InvokeChooser<T, K>(Action<T> initCallback = null)
   2:     where K : TaskEventArgs
   3:     where T : ChooserBase<K>, new()
   4: {
   5:     TaskCompletionSource<K> tcs = new TaskCompletionSource<K>();
   6:     T chooser = new T();
   7:     
   8:     if (initCallback != null)
   9:         initCallback(chooser);
  10:     
  11:     EventHandler<K> handler = null;
  12:     
  13:     handler = (s, e) =>
  14:     {
  15:         chooser.Completed -= handler;
  16:     
  17:         if (e.Error != null)
  18:             tcs.SetException(e.Error);
  19:         else
  20:             tcs.SetResult(e);
  21:     };
  22:     
  23:     chooser.Completed += handler;
  24:     chooser.Show();
  25:     
  26:     return tcs.Task;
  27:     }

Let me explain. First of all, an instance of the TaskCompletionSource<T> class is created. This class wraps a task that is returned to the caller to be awaited. This task ends when the SetResult, SetException or SetCancelled methods are called. Then the chooser is created from the generic type, the instance is passed to the initialization callback. After this part the code creates an event handler and, using a lambda expression, it attach a method to handle the result. Finally the chooser is shown and the task is returned.

Inside the lambda expression, the first action is to detach the event handler. This clean every reference to the handler and leave the instance free to be finalized. On the basis of the result (success or failure) the SetException and SetResult methods are a called. This ends the await and eventually returns the result or the exception.

The next is to use this method to create some chooser-specific methods that let the user easily specify the arguments. Here is the ChoosePhoto method:

   1: public static async Task<Stream> ChoosePhoto(bool showCamera = true)
   2: {
   3:     var r = await DeviceServices.InvokeChooser<PhotoChooserTask, PhotoResult>(
   4:         t =>
   5:         {
   6:             t.ShowCamera = showCamera;
   7:         });
   8:  
   9:     return r.ChosenPhoto;
  10: }

In my class I've created a number of these methods, and all of them are targeted to the specific chooser they use. This method collects the hard part into a single and clean solution exposing a bunch of clear methods that simplify the developer life. Here is the full code you can cut & paste in your projects:

/// <summary>
/// Implement services to connect to device
/// </summary>
public static class DeviceServices
{
/// <summary>
/// Chooses the photo.
/// </summary>
/// <param name="showCamera">if set to <c>true</c> [show camera].</param>
public static async Task<Stream> ChoosePhoto(bool showCamera = true)
{
var r = await DeviceServices.InvokeChooser<PhotoChooserTask, PhotoResult>(
t =>
{
t.ShowCamera = showCamera;
});

return r.ChosenPhoto;
}

/// <summary>
/// Chooses the address.
/// </summary>
public static async Task<NamedValue<string>> ChooseAddress()
{
var r = await DeviceServices.InvokeChooser<AddressChooserTask, AddressResult>();
return new NamedValue<string> { DisplayName = r.DisplayName, Value = r.Address };
}

/// <summary>
/// Chooses the email.
/// </summary>
public static async Task<NamedValue<string>> ChooseEmail()
{
var r = await DeviceServices.InvokeChooser<EmailAddressChooserTask, EmailResult>();
return new NamedValue<string> { DisplayName = r.DisplayName, Value = r.Email };
}

/// <summary>
/// Chooses the phone number.
/// </summary>
public static async Task<NamedValue<string>> ChoosePhoneNumber()
{
var r = await DeviceServices.InvokeChooser<PhoneNumberChooserTask, PhoneNumberResult>();
return new NamedValue<string> { DisplayName = r.DisplayName, Value = r.PhoneNumber };
}

/// <summary>
/// Saves the phone number.
/// </summary>
/// <param name="phoneNumber">The phone number.</param>
public static async Task SavePhoneNumber(string phoneNumber)
{
var r = await DeviceServices.InvokeChooser<SavePhoneNumberTask, TaskEventArgs>(
t =>
{
t.PhoneNumber = phoneNumber;
});
}

/// <summary>
/// Saves the email.
/// </summary>
/// <param name="emailAddress">The email address.</param>
public static async Task SaveEmail(string emailAddress)
{
var r = await DeviceServices.InvokeChooser<SaveEmailAddressTask, TaskEventArgs>(
t =>
{
t.Email = emailAddress;
});
}

/// <summary>
/// Invokes the chooser.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
/// <param name="initCallback">The initialize callback.</param>
private static Task<K> InvokeChooser<T, K>(Action<T> initCallback = null)
where K : TaskEventArgs
where T : ChooserBase<K>, new()
{
TaskCompletionSource<K> tcs = new TaskCompletionSource<K>();
T chooser = new T();

if (initCallback != null)
initCallback(chooser);

EventHandler<K> handler = null;

handler = (s, e) =>
{
chooser.Completed -= handler;

if (e.Error != null)
tcs.SetException(e.Error);
else
tcs.SetResult(e);
};

chooser.Completed += handler;
chooser.Show();

return tcs.Task;
}
}

Hoping this helps!

Review: One week with Lumia 925

2013-10-03T23:04:28+01:00 by Andrea Boschin

WP_20131003_004During last 7 days I had the pleasure of having a Nokia Lumia 925, thanks to the #ilmiolumia program by Nokia Italy. I've subscribed in this page http://slpg.org/18V9Rdj (Italy only I suppose) and few days later they called me because I've been selected to have a try with this device.

When the device arrived and I unpacked it, I have to confess a little delusion. I really would want to have a try with a Lumia 1020, with its amazing 41mp camera, so when I discovered the device was a Lumia 925, I was little disappointed. Few moments later, keeping it in my hands for a little, just before to switch it on, I realized it is really a nice device, really light in weight, and with a stylish line. It immediately captured my love for minimal design with its metal body that appear so attractive for eyes.

The Lumia 925, differently from other Lumia smartphones, like 820, 920 and also the 1020, is externally a device tailored for business man, for the elegant woman that needs to have a phone beautiful and attractive when in the hands but light and invisible when in the pocket or in the purse.

When it is switched on it present the familiar tiles of Windows Phone 8, with a number of applications already on board. Entering the live id I use for my 820, it automatically synchronized apps and data. The operation taken some minutes to complete but at the end I found everything I need, with the exception of tiles positioning that has been completely lost. Also I had to remove some applications that the device is unable to synchronize just because the have a newset version already installed.

I've explored the device for a few and I found that the power of its 1,5 ghz dual core processor makes the navigation very fluid and the applications really fast and stepless. The CPU is exactly the same as my 820 and definitely it is perfect for device features. The device has 16GB on board memory but, and this is a bad note, is haven't a slot for memory expansion. WP_20130928_11_56_21_Smart16GB may appear a huge amount of memory but when you start storing some music and pictures the main memory can rapidly become little. In my 820 the 8GB main memory I only use for apps is insufficient and, due to a strange memory management by the operating system, it refuses to install some memory-hungry applications (e.g. some games). Given you may use half the size to store your files, the remaining half could suffer of the same problem. In my opinion the best would be to have equipped the device with 32gb or alternatively with an SSD slot.

Finally I focused my attention to the very interesting part of the device. The 8,7mp camera. When you start with camera, the default application is disappointing but, after a few you discover two apps that boosts its power to the max. Nokia Smart Camera and Nokia Pro Camera are able to take the maximum advantage from th camera. The first, Nokia Smart Camera, is interesting to take action shots because is able to shoot a fast sequence of images and then elaborate to find the best one or play with moving subjects. The image of me on the side is taken and elaborated with this software. It wp_ss_20131003_0014shows an enjoying effect that shows the shoot sequence. The image is completely customized on board of the phone an it may be modified easily in a secondary time.

The smart cam is beautiful and you will enjoy your friends with your shoots. A much more interesting use is to take sport actions where multiple sequential shoots can help to choose the imagethat better represents the moment. But for an exigent person it is someway trivial.

For such people the Nokia Pro Cam is for sure a dream made reality while it puts in your hands a really professional camera, with a really fast as the light shoot speed. The software gives a number of tuning trimmers, with an effective user interface. You can tune flash, zoome, ISO, shooter speed and exposure. But the very surprising is the ability to manipulate the focus the enables the deep field effect.

wp_ss_20131003_0024The phone made me very satisfied along the week I used it. It is for sure a wonderful device and it made me forget the powerfulness of the Lumia 1020. I'm still attracted by this device due to the 41mp camera that I suppose should add much more control to camera, but watching ad the balance of features, the Lumia 925 is almost the perfect device for who wants a powerful device, with a amazing camera that is able to shoot in low light conditions and make wonderful photograps, but he also wants a compact, light and stylish phone to be used for professional activities. The operating system is to me a great companion for such people, thaks to the integration with work environment thanks to Office hub and a huge number of apps.

My congrats to Nokia for its best device ever, waiting for an hoped "Lumia 1025" (?) that mixes the huge 41mp camera together with the class of the 925.

From a "Class Library" to a "WinRT Component": Deal with inheritance

2013-09-26T23:32:39+01:00 by Andrea Boschin

If you ever tryed to take a class library written in C# for a Windows Store app and act on the "Output Type" dropdown list to convert it to a Windows Runtime Component, you have been probably discouraged by the huge number of errors this, apparently simply action, generates. If your library is something more complex than some basic classes and it has been writing with object orientation in mind, the conversion to a WinRT Component is far far away to be a simple task.

To fully understand the reason, you have to keep in mind the lower target, this component has, that is Javascript. So now, you have to try to think to the wonderful toolset you have in your hands when you write in C# and ask yourself what is the corresponding construct in Javascript.

Let do some examples: Generic Types? they do not exist in Javascript.  Inheritance? It's only simulated in Javascript. Types are limited to a restricted set, the language only supports arrays, and the asynchronous model is something of really different in Javascript.

All these things can't be used in a WinRT component. Precisely, they can be used inside a component, but they can't be exposed to other languages than C# because the projection engine is not able to convert them to Javascript's corresponding constructs.

With these posts I'd like to show how to convert, relatively easily, an existing library, made with the full toolset of C#, in a fully functional WinRT component without wasting lot of time rewriting the most of the library.

Let start from something: Flickr Tools

During my last talk in Venice, I had to present a lab about sharing contracts. In this talk I had the need of creating a simple Windows Store app on the basis of I've presented the arguments. To have an interesting and functional application I've created a simple class library, that is able to call Flickr APIs to retrieve some photographs for the purposes of the presentation. The library, called XPG.FlickrTools has been written with the full usage of inheritance, generics, and types, without any caution for the Javascript side of the story. It simply did not have any interest to me in that moment.

Then after the lab have been done, taken by curiosity I've tried to convert the library to a WinRT component and I found a number of errors:

image

I known that the task is not only to take a dropdownlist down, but the number of errors (15 at the start, but they only hide a greatest number) was totally unexpected. So, my very first task in the conversion have been to convert each class to "internal", to simply hide them to the projection engine. I think it should be the very first step in every conversion because it remove all the errors and let you act one step at the time

This task does not suffice to remove all the errors. Infact, a WinRT component needs to contains almost a public type to be a real component. Differently it generates at least the following:

"Input module must contain at least one public type that is located inside a namespace. The only types found inside namespaces are private."

Now let me introduce the concept to apply to start the conversion. It is really true you are not able to use inheritance in classes so something like this is not legal in a WinRT component:

   1: public class FlickrSearch : FlickrPagedCall
   2: {
   3:     // omissis
   4: }

This is because you need to declare the FlickrSearch class and each other public type "sealed", so you implicitly cut off the inheritance. Once FlickrPagedCall is sealed, the FLickrSearch class cannot inherits from it. Fortunately, inheritance is supported in interfaces so this code is perfectly legal:

   1: public interface  IFlickrSearch : IFlickrPagedCall
   2: {
   3:     // omissis
   4: }

To fully take advantage of this I have to recall that an "internal" type cannot be instantiated by an external assembly, but it can cross the boundaries of the assembly where it have been created if it implements a public interface to handle it. So, I have simple to make the internal component implement the public interfaces. Let start creating an interface for each type it has to be projected:

   1: internal class FlickrSearch : FlickrPagedCall, IFlickrSearch 
   2: { }
   3:  
   4: internal class FlickrPagedCall : FlickrCall, IFlickrPagedCall 
   5: { }
   6:  
   7: internal class FlickrCall : IFlickrCall
   8: { }

Doing this task requires some kind of careful. In my library I have nine classes that needs to be converted to interfaces. First I added an interface to each class prepending an "I" to the class name. Then I added the interface to the implementation list of the corresponding class:

   1: public interface IFlickrCall
   2: {
   3: }
   4:  
   5: internal abstract class FlickrCall : IFlickrCall
   6: {
   7: }

Then I take care of inheritance at the interface level, adding the correct base interface to each interface I previously defined. At the moment I leave the interfaces empty just because taking care of methods may be slightly complicated, so I prefer to make the library free of errors before the next steps.

I need to be really careful when classes have some special inheritance list. In my case the FlickrResponse class implements "IEnumerable<FlickrPhoto>". IEnumerable generic classes are perfectly legal in winRt components but they have to espose public types and not internal ones. So this:

   1: internal sealed class FlickrResponse : IEnumerable<FlickrPhoto>
   2: {
   3: }

May be converted to this:

   1: public interface IFlickrResponse : IEnumerable<IFlickrPhoto>
   2: {
   3: }
   4:  
   5: internal sealed class FlickrResponse : IEnumerable<IFlickrPhoto>, IFlickrResponse
   6: {
   7: }

Obviously you need to convert to the right interface all the places where a concrete class is returned. In this case the FlickrPhoto class is converted to the corresponding IFlickrPhoto interface. Upto the total conversion has been completed you should have a number of errors. Simply forget the errors and take the maximum care in conversion. Here another example:

   1: protected async Task<FlickrResponse> Execute(Uri uri)
   2: { }

It becomes:

   1: protected async Task<IFlickrResponse> Execute(Uri uri)
   2: { }

You have also to start adding properties and method to classes declarations.This happens when an object is used inside a method.

At the end the library soud compile again. Now we have a problem: the interfaces cannot be instantiated, just because they are interfaces, not classes... so we need someone that creates classes internally and then return it by interfaces. It is called a "factory".

   1: public sealed class FlickrFactory
   2: {
   3:     public string AppKey { get; private set; }
   4:     public string Secret { get; private set; }
   5:  
   6:     public FlickrFactory(string appKey, string secret)
   7:     {
   8:         this.AppKey = appKey;
   9:         this.Secret = secret;
  10:     }
  11:  
  12:     public IFlickrSearch CreateSearch(string query, int number)
  13:     {
  14:         return new FlickrSearch(query, this.AppKey, this.Secret);
  15:     }
  16: }

After this passage your library should be near to fully compile. Mine has still some issue, but it is not related to the inheritance problem. I'll be back on these additional problems in the next post, speaking about asyncronicity.

#wp8tip: Adapt images to different resolutions

2013-04-23T23:32:03+01:00 by Andrea Boschin

Windows Phone 8 comes with the support of multiple resolutions, that must be supported by new applications to cover all the available devices. As you can understand, it is really important to be able to support these new resolutions seamless, but it may be annoying when we have to deal with a number of images. Indeed, if vector graphics scales directly to all the resolutions, at the sole price of correctly design yout layout, with images you are forced to provide a different size to every resolution, if you want the best result.

To make my life easy, I wrote a simple attached property that enable me to easily specify the path of the image and have it updated with a resolution suffix. It is something similar to which it happens automatically in Windows 8. First of all a mini helper to convert an uri and add the resolution switch the path:

   1: public static class ResolutionHelper
   2:  {
   3:      public static Uri ToCurrentResolution(this Uri uri)
   4:      {
   5:          string uriString = uri.OriginalString;
   6:  
   7:          if (uriString.EndsWith(".jpg") || uriString.EndsWith(".jpeg") || uriString.EndsWith(".png"))
   8:          {
   9:              int dot = uriString.LastIndexOf('.');
  10:              uriString = uriString.Substring(0, dot) + "." + ResolutionHelper.CurrentResolutionString + uriString.Substring(dot, uriString.Length - dot);
  11:              return new Uri(uriString, UriKind.RelativeOrAbsolute);
  12:          }
  13:  
  14:          return uri;
  15:      }
  16:  
  17:      private static string CurrentResolutionString
  18:      {
  19:          get
  20:          {
  21:              if (App.Current.Host.Content.ScaleFactor == 100)
  22:                  return "screen-wvga";
  23:              else if (App.Current.Host.Content.ScaleFactor == 160)
  24:                  return "screen-wxga";
  25:              else if (App.Current.Host.Content.ScaleFactor == 150)
  26:                  return "screen-720p";
  27:              else
  28:                  throw new InvalidOperationException("Unknown resolution");
  29:          }
  30:      }
  31:  }

Once I have this tool class ready, it's easy to imagine to specify an uri to the image source and have it converted on the basis of the current resolution. I've tried a number of solutions but I finally found that writing a simple Attached property is the most simple and effective. Here is the extension:

   1: public class AutoScale : DependencyObject
   2: {
   3:     public static readonly DependencyProperty SourceProperty =
   4:         DependencyProperty.RegisterAttached("Source", typeof(Uri), typeof(Image), new PropertyMetadata(null));
   5:  
   6:     public static Uri GetSource(DependencyObject obj)
   7:     {
   8:         return (Uri)obj.GetValue(SourceProperty);
   9:     }
  10:  
  11:     public static void SetSource(DependencyObject obj, Uri value)
  12:     {
  13:         obj.SetValue(SourceProperty, value);
  14:  
  15:         Image image = obj as Image;
  16:  
  17:         if (image != null)
  18:         {
  19:             image.Source = new BitmapImage(value.ToCurrentResolution());
  20:         }
  21:     }
  22: }

The attached property has the advantage of making the trick seamless. Instead of writing the Source property in the XAML, I write tha "local.AutoScale.Source" property and is automatially update the underlying image:

   1: <Image local:AutoScale.Source="/Assets/Images/img.jpg" 
   2:        HorizontalAlignment="Center" 
   3:        VerticalAlignment="Center" Width="300" Height="300"/>

Tip: a common error with Dependency Property metadata

2013-01-22T23:54:03+01:00 by Andrea Boschin

Recently someone pointed me to a malfunction on one of my examples. He sent me a repro project and, after I've run the example, I found the problem as he described it to me. But it took me a long time to figure out the reason. The problem was really simple: an instance of a templated control in a page seems to share a property with another instance of the same control in another page... This sounds impossible at first sight but if the property is a Dependency Property the issue is real. Here is the original code:

   1: public static readonly DependencyProperty ParallacticLayersProperty =
   2:     DependencyProperty.Register(
   3:         "ParallacticLayers", 
   4:         typeof(List<FrameworkElement>), 
   5:         typeof(ParallacticGridView), new PropertyMetadata(new List<FrameworkElement>()));

The code above may appear correct but it has an important issue. When a dependency property is used with a collection type, it is important to not initiate the metadata inline with the declaration, because the declaration of a static property only create a single instance that is shared by all the controls that use thid property. The correct example is the following:

   1: public static readonly DependencyProperty ParallacticLayersProperty =
   2:     DependencyProperty.Register(
   3:         "ParallacticLayers", 
   4:         typeof(List<FrameworkElement>), 
   5:         typeof(ParallacticGridView), new PropertyMetadata(null));

The collection datatypes only, make this problem evident, because once the property has been initialized it does not change the value. The observed behavior shows that the collection always adds the items without removing them. This apply to every XAML dialect...

Customized semantic zoom: an alternative to common grouping

2013-01-18T01:36:55+01:00 by Andrea Boschin

A really distinctive aspect of the Windows Store apps is a completely new way of displaying information, that not only suggest a very simplified design able to improve the importance of content, but also introduces new paradigms to make easy to browse the structure of the information. So they born a number of controls that supports scrolling beyond the size of the screen, that display elements of the right dimension for the fingers, that easily enable grouping to make simple to reach what the user needs. The cutting edge of this completely new interface if for seru the semantic zoom control that adds a thrid dimension to the browsing of data enabling a flawless navigation over grouped information.

The pinch and zoom gesture is becoming a common habit while using a Windows Store app but unfortunately the developers have always used this control as-is, without experimenting other ways of use the Semantic Zoom views. What people always forget is that the Semantic Zoom control is easily extensible and, with a low effort it is possible to create controls that shows customized views for one of the zoom levels or both.

During the development of the my app "EarthQuake Alerts" I've tried to overcome the now common groups/items way of using this control creating a map for the zoomed-out view. In the figure below you can see the two view of the main screen of the app.

screenshot_01172013_000205 screenshot_01172013_000210

As you can see while the zoomed-in view is a common GridView displaying grouped items, the zoomed out view shows a map with a number of flags. To understand the meaning of the flags you are to be aware that each flags belogs to a group in the SemanticZoom zoomed in. The position of the flag is calculated as the medium point between all the coordinates belonging to a group.

Implementing the ISemanticZoomInformation

If you explore the documentation of the two controls that currently can be used as part of a semantic zoom view you can see that both the GridView and ListView implement the ISemanticZoomInformation. Infact this interface is directly used by the SemanticZoom control to send and receive information about the interaction of the user to change the visual state. So from a point of view a control can notify about the selection of an item and the SemantiZoom acts changing the view from one to the other pointing the focus to the selected group or item. On the other side the SemanticZoom can ask the target to focus an item or notify when a change starts or ends. The interface contains a number of methods and properties. Here you can view the complete documentation on MSDN: http://slpg.org/VavDrp

In my case the implementation was very simple because the target map does not need to complex interactions like focusing an element. This is because the map extends to the whole screen and the focus is not really useful .The sole interaction I need to handle is the click on a flag that have to switch to the secondary view. To get this working I used the SemanticZoomOwner property. This property give a reference to the SemanticZoom that contains the control. So every time I receive the click of an item I call the following method:

   1: private void ApplySemanticZoom(IGeographicGroup<IGeographicPoint> item)
   2: {
   3:     this.CurrentItem = item;
   4:     this.SemanticZoomOwner.ToggleActiveView();
   5: }

This simple call is able to switch from the current mode (the map in ZoomedOut) an the detail (the ZoomedIn). After the switch has started you have to take care of some other aspects. These are implemenetd overriding some other simple methods:

   1: public void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
   2: {
   3:     source.Item = this.CurrentItem;
   4:     destination.Item = this.CurrentItem;
   5: }
   6:  
   7: public void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
   8: {
   9:     destination.Item = source.Item;
  10: }

The first override is called when the control has started the swith from itself to the alternative view. In this method I set the Destination as the selected item. In the other method, when the control is called I simply set the destination as the source. Remember that the CurrentItem property contanis the element clicked.

Really it is all what you need to do. Given the very few documentaion on the internet I spend some hours to understand the point. But after I understand the meaning of every method the implementation has become easy like a breeze.

Windows 8 apps: Make your GridView parallactic

2012-10-24T00:46:33+01:00 by Andrea Boschin

Few months ago I wrote a post about a way to apply a parallactic effect to a GridView. Given that I explained the meaning of the "parallactic" term in that post, I assume you already know it. Unfortunately, the solution I explained was based on the use of a ScrollViewer to wrap a GridView. This was because the ScrollViewer exposes the ViewChanged event but the GridView don't. This is a minor issue in some cases, but lot of times the scrolling is not so smooth and fluid as the one of the GridView. Luckily XAML is so smart and beautiful that offers an alternative solution as the following video shows:

You have to be aware that all XAML controls are template based, as they are in Silverlight, and if you explore the template of the GridView you notice that is is based on an internal ScrollViewer. So, the idea is really simple in words; I can inherit a new control from the GridView, subtly change the template and attach to ScrollViewer events to update the parallactic background. Simle to say as it is simple to implement. First of all we have to change the template:

   1: <Setter Property="Template">
   2:     <Setter.Value>
   3:         <ControlTemplate TargetType="local:ParallacticGridView">
   4:             <Grid Background="{TemplateBinding Background}">
   5:                 <ItemsControl x:Name="ParallacticLayersElement" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
   6:                     <ItemsControl.ItemsPanel>
   7:                         <ItemsPanelTemplate>
   8:                             <Grid />
   9:                         </ItemsPanelTemplate>
  10:                     </ItemsControl.ItemsPanel>
  11:                 </ItemsControl>
  12:                 <Border BorderBrush="{TemplateBinding BorderBrush}" 
  13:                     BorderThickness="{TemplateBinding BorderThickness}" 
  14:                     Background="Transparent">
  15:                     <ScrollViewer x:Name="ScrollViewer" 
  16:                                   BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" 
  17:                                   HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" 
  18:                                   HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" 
  19:                                   IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" 
  20:                                   IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" 
  21:                                   IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" 
  22:                                   IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" 
  23:                                   IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" 
  24:                                   TabNavigation="{TemplateBinding TabNavigation}" 
  25:                                   VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" 
  26:                                   VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" 
  27:                                   ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"
  28:                                   Background="Transparent">
  29:                         <ItemsPresenter HeaderTemplate="{TemplateBinding HeaderTemplate}" 
  30:                                         Header="{TemplateBinding Header}" 
  31:                                         HeaderTransitions="{TemplateBinding HeaderTransitions}" 
  32:                                         Padding="{TemplateBinding Padding}" />
  33:                     </ScrollViewer>
  34:                 </Border>
  35:             </Grid>
  36:         </ControlTemplate>
  37:     </Setter.Value>
  38: </Setter>




The yellow parts are the changes respect the original template. The add an outer grid that is used to contains the internal elements together with the added backgrounds. The ItemsControl instead let you to add a number of background elements that will be showed under the generated items, one on top of the other. The code is a fragment of a template that has to be put inside the generic.xaml. The next step is to implement the class of the control:

   1: public class ParallacticGridView : GridView
   2: {
   3:      private ItemsControl ParallacticLayersElement { get; set; }
   4:      private ScrollViewer ScrollViewer { get; set; }
   5:  
   6:      public static readonly DependencyProperty ParallacticLayersProperty =
   7:          DependencyProperty.Register("ParallacticLayers", typeof(List<FrameworkElement>), typeof(ParallacticGridView), new PropertyMetadata(new List<FrameworkElement>()));
   8:  
   9:      public List<FrameworkElement> ParallacticLayers
  10:      {
  11:          get { return (List<FrameworkElement>)GetValue(ParallacticLayersProperty); }
  12:          set { SetValue(ParallacticLayersProperty, value); }
  13:      } 
  14:  
  15:      public ParallacticGridView()
  16:      {
  17:          this.DefaultStyleKey = typeof(ParallacticGridView);
  18:      }
  19:  
  20:      protected override void OnApplyTemplate()
  21:      {
  22:          this.ParallacticLayersElement = this.GetTemplateChild("ParallacticLayersElement") as ItemsControl;
  23:  
  24:          foreach (FrameworkElement element in this.ParallacticLayers)
  25:              this.ParallacticLayersElement.Items.Add(element);
  26:  
  27:          this.ScrollViewer = this.GetTemplateChild("ScrollViewer") as ScrollViewer;
  28:          this.ScrollViewer.ViewChanged += ScrollViewer_ViewChanged;
  29:          base.OnApplyTemplate();
  30:      }
  31:  
  32:      private void ScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
  33:      {
  34:          foreach (FrameworkElement element in this.ParallacticLayersElement.Items.OfType<FrameworkElement>())
  35:          {
  36:              Thickness thickness = element.Margin;
  37:              var deltaX = (this.ScrollViewer.HorizontalOffset / this.ScrollViewer.ScrollableWidth) * (element.ActualWidth - this.ScrollViewer.ViewportWidth);
  38:              thickness.Left = -deltaX;
  39:              element.Margin = thickness;
  40:          }
  41:      }
  42:  }

The control has a ParallacticLayers property that is used to specify the items on the background. In the OnApplyTemplate I get a reference to the elements I need to manipulate. First of all the ScrollViewer which I attach the ViewChanges event. In the event handler I calculate the position of each layer with the same formula I've used in the previous article. To use the new control you can operate as follow:

   1: <controls:ParallacticGridView x:Name="gv" SelectionMode="None">
   2:     <controls:ParallacticGridView.ParallacticLayers>
   3:         <Image Stretch="UniformToFill" Source="Assets/Montreal_Twilight_Panorama_2006.jpg" Margin="0,0,0,0" />
   4:     </controls:ParallacticGridView.ParallacticLayers>
   5:     <controls:ParallacticGridView.ItemTemplate>
   6:         <DataTemplate>
   7:             <Border Width="150" Height="150" Background="#88FFFFFF" BorderThickness="1" BorderBrush="#88000000">
   8:                 <TextBlock FontSize="24" Text="{Binding}" 
   9:                            HorizontalAlignment="Center" 
  10:                            VerticalAlignment="Center" 
  11:                            Foreground="Black" />
  12:             </Border>
  13:         </DataTemplate>
  14:     </controls:ParallacticGridView.ItemTemplate>
  15:     <controls:ParallacticGridView.ItemsPanel>
  16:         <ItemsPanelTemplate>
  17:             <VariableSizedWrapGrid MaximumRowsOrColumns="4" VerticalAlignment="Top" Margin="100,100,100,0" />
  18:         </ItemsPanelTemplate>
  19:     </controls:ParallacticGridView.ItemsPanel>
  20: </controls:ParallacticGridView>

Interesting, in the ParallacticLayers property you can put more that one background. The result will be a set of backgrounds that scroll at a different speed.

Download: Elite.Parallactic.zip (7MB)

Windows 8 Apps: Change your project to run PlayReady successfully

2012-09-22T23:29:25+01:00 by Andrea Boschin

Today I wasted a lot of time to understand why, the code I wrote to implement PlayReady in a Windows 8 App didn’t work. I have ran the code lot of times, making changes to handle obscure hypothesis, just because my application was failing to load a DRM protected stream. When I finally found the error code issued by the MediaFailed event I went on the right way:

MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT – 0x800700C1

I convinced myself that the problem wasn’t in the code but probably in the context I was compiling, this because the error 0x800700C1 means “is not a valid Win32 application”.

Comparing the project configuration with the one in the samples, I found the answer in a simple flag in the project configuration:

image

The “prefer 32-bit” flag is a new entry in the projects that target Microsoft .NET Framework 4.5. Its meaning is explained well in this post but in a few words in my case it was forcing the compiler to output to x86 (32-bit) instead of x64. Unfortunately PlayReady only supports 64bit runtime so, when the application ran it failed with the code I reported above.

So, when you’ll have to write applications that take advantage of the PlayReady SDK, please always remember to clear this flag because it is the sole way to have it working.

Windows 8 Metro series part #1

2012-09-12T00:25:31+01:00 by Andrea Boschin

Today, the last article of my series about Windows 8 "metro” applications I’m writing for http://www.silverlightshow.net has been published. The article is the first of the second part so it is the moment to collect together the work I’ve done up to july for the first part. If you like, the articles are available online on the SilverlightShow’s website at the addresser here reported:

 

Thanks to the great work the team made, the series is also available in a useful e-book, in the most common formats for your e-reader. You can buy it on the same website at this address http://www.silverlightshow.net/ebooks/win8_metro_1.aspx for only $2,99.

Metro: The SemanticZoom and the missing ItemTemplateSelector for ZoomedOutView

2012-09-07T23:41:11+01:00 by Andrea Boschin

Did you ever try to use the ItemTemplateSelector property for a grid view in SemanticZoom’s ZoomedOutView property? So the question is simpler than it appear: take a GridView, used to show items in a semantic zoom, - when the user zooms out - and try to give a different template to each item, using the usual template selector. And the answer is also simple: it does not work.

I suppose there is a good reason for this problem, but what it really matter to me is the solution. In a recent project I developed, the problem was really annoying and, after lot of try I found a work-around. The first thing to do is to setup the ZoomedOutView property:

   1: <SemanticZoom.ZoomedOutView>
   2:     <GridView ItemTemplate="{StaticResource ZoomedOutItemTemplate}" SelectionMode="None">
   3:         <GridView.ItemsPanel>
   4:             <ItemsPanelTemplate>
   5:                 <WrapGrid ItemWidth="300" ItemHeight="150" 
   6:                           VerticalAlignment="Center" HorizontalAlignment="Center" />
   7:             </ItemsPanelTemplate>
   8:         </GridView.ItemsPanel>
   9:     </GridView>
  10: </SemanticZoom.ZoomedOutView>

This is easy to understand given that there is nothing new. Please take only note I specified a simple ItemTemplate where the trick happens. The work-around is to use a ContentControl to map binding information and use the ContentTemplateSelector in place of the ItemTemplateSelector that is not working:

   1: <DataTemplate x:Key="ZoomedOutItemTemplate">
   2:     <ContentControl DataContext="{Binding Group}" Content="{Binding DataContext, RelativeSource={RelativeSource Mode=Self}}">
   3:         <ContentControl.ContentTemplateSelector>
   4:             <local:SemanticZoomTemplateSelector
   5:                 MajorTemplate="{StaticResource ZoomedOutItemMajorTemplate}"
   6:                 MinorTemplate="{StaticResource ZoomedOutItemMinorTemplate}"
   7:                 LightTemplate="{StaticResource ZoomedOutItemLightTemplate}"
   8:                 StrongTemplate="{StaticResource ZoomedOutItemStrongTemplate}"
   9:                 ModerateTemplate="{StaticResource ZoomedOutItemModerateTemplate}" />
  10:         </ContentControl.ContentTemplateSelector>
  11:     </ContentControl>
  12: </DataTemplate>

The tricky part of the solution is into the DataBinding of the ContentControl. If you simply try to bind the source property to the Content property, the template selector is not applied. I supposed the reason has to be found in the way the data binding happens so I had the idea of binding the property twice: first of all I bind the source to the DataContext property and then I use the RelativeSource to bind the Content property to the DataContext. And… it works!

Now I can implement the a Template selector to assign the right template based on the values of the source item:

   1: public class SemanticZoomTemplateSelector : DataTemplateSelector
   2: {
   3:     public DataTemplate MinorTemplate { get; set; }
   4:     public DataTemplate MajorTemplate { get; set; }
   5:     public DataTemplate ModerateTemplate { get; set; }
   6:     public DataTemplate StrongTemplate { get; set; }
   7:     public DataTemplate LightTemplate { get; set; }
   8:  
   9:     public SemanticZoomTemplateSelector()
  10:     {
  11:     }
  12:  
  13:     protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
  14:     {
  15:         EarthquakeGroup group = item as EarthquakeGroup;
  16:  
  17:         if (group != null)
  18:         {
  19:             if (group.Level == "major")
  20:                 return MajorTemplate;
  21:             if (group.Level == "minor")
  22:                 return MinorTemplate;
  23:             if (group.Level == "moderate")
  24:                 return ModerateTemplate;
  25:             if (group.Level == "strong")
  26:                 return StrongTemplate;
  27:         }
  28:  
  29:         return LightTemplate;
  30:     }
  31: }

The best thing of this solution is that the ContentControl does not changes how the item is shown. It does not require any change to the data templates and you can also use a resource dictionary.

If the solution is not clear here is a downloadable example: http://xamlplayground.org/assets/sources/XPG.MetroQuakes.zip (22kb)

Consume a Socket using Reactive Extension

2011-06-29T09:43:23+01:00 by Andrea Boschin

In my last post I wrote about writing a TCP server using the Reactive Extensions library. It was not a Silverlight related post, but it simply introduces the server side component that I will use in this post to show you how to use the same library to consume the incoming data and present it in Silverlight. The interesting part is to understand how rx can simplify the programming model when dealing with asynchronicity both in Silverlight and in server side full .NET programming.

The server I presented was a very simple socket listener that waits for connections and then, when the channel has been established, it push to the client a continuous stream of data that represent the current state of the CPU and memory of the server. With this huge amount of informations incoming we can create a little application that is able to show a chart and some gauges, updated almost in realtime.

The application, developed following the MVVM pattern, is made of a simple view containing the controls used to present the informations. These controls are feeded by a couple of properties in the ViewModel that are updated with the incoming data. So the most of the work is done by the ViewModel that is responsible of connecting to the socket and read the information stream to update the properties. In a real world solution probably you will have some kind of layer between the ViewModel and the socket, but for the sake of the post we will keep it simple as much as we need to understand how it works.

Consuming a socket in Silverlight means using an instance of the Socket class that represents the connection and a SocketAsyncEventArgs that is used when you call the methods of the connection to make the requests and receive responses. So, as an example, when you have to establish the connection you have to create the instance of the Socket class and the call the ConnectAsync method providing the SocketAsyncEventArgs initialized with the address of the endpoint to connect to. When the connection has been established the SocketAsyncEventArgs class will raise a Completed event that notify about the result of the operation. Doing it with Reactive Extensions mean something like this:

   1: protected void Connect()
   2: {
   3:     this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   4:  
   5:     SocketAsyncEventArgs arguments = new SocketAsyncEventArgs();
   6:     arguments.RemoteEndPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4530);
   7:  
   8:     var socketAsObservable = from args in Observable.FromEvent<SocketAsyncEventArgs>(
   9:                                  ev => arguments.Completed += ev,
  10:                                  ev => arguments.Completed -= ev)
  11:                              select args.EventArgs;
  12:  
  13:     socketAsObservable
  14:         .Where(args => args.LastOperation == SocketAsyncOperation.Connect)
  15:         .Subscribe(
  16:         args =>
  17:         {
  18:             args.Dispose();
  19:             this.Receive();
  20:         });
  21:  
  22:     this.Socket.ConnectAsync(arguments);
  23: }

In the line #3 it is created the Socket with the common parameter that is used in Silverlight for a TCP channel. Then an instance of the SocketAsyncEventArgs is initialized and its property RemoteEndPoint is provided with and instance of DnsEndPoint that represente the address of the server to connect to. The port is 4530 like we defined in the previour article.

At this point it is created a stream, called socketAsObservable, from the Completed event of the SocketAsyncEventArgs. the stream filter the LastOperation to be "Connect", as we expect and in the Subscribe method disposes the SocketAsyncEventArgs instance and starts to receive data. The SocketAsyncEventArgs instance can be used only once so we have to carefully dispose it to avoid memory leaks.

Once the connection has successfully established you have to put your socket in Receive. When incoming data is detected you will be notified and you can fetch it from the SocketAsyncEventArgs and put again the socket in Receive. Here is how it appear with Reactive Extensions:

   1: protected void Receive()
   2: {
   3:     SocketAsyncEventArgs arguments = new SocketAsyncEventArgs();
   4:     arguments.SetBuffer(new byte[1024], 0, 1024);
   5:  
   6:     var socketAsObservable = from args in Observable.FromEvent<SocketAsyncEventArgs>(
   7:                                  ev => arguments.Completed += ev,
   8:                                  ev => arguments.Completed -= ev)
   9:                              select args.EventArgs;
  10:  
  11:     socketAsObservable
  12:         .Where(args => args.LastOperation == SocketAsyncOperation.Receive)
  13:         .Throttle(TimeSpan.FromMilliseconds(500))
  14:         .ObserveOnDispatcher()
  15:         .Subscribe(OnReceive);
  16:  
  17:     if (this.Socket.Connected)
  18:         this.Socket.ReceiveAsync(arguments);
  19: }

Once again we create the instance of the SocketAsyncEventArgs. It is now initialized with a SetBuffer that allocates a buffer of 1 KByte that is used by the socket to compy the incoming data. Then the socketAsObservable is created using the FromEvent; This method is important because it is in charge of attaching and detaching the Completed event so we avoid to have unwanted delegates around. Again the socketAsObservable is filtered selecting only when LastOperation equals to Receive and we also apply a Throttling of about 500 milliseconds. It is made to discart updated when they are too fast. One update every half a second suffice to say that the UI is up to date with the server.

Fially we marshal the stream to the UI Thread using the ObserveOnDispatcher and the received events are forwarded to the OnReceive method that is responsible of parsing the received data and updating the UI.

   1: protected void OnReceive(SocketAsyncEventArgs args)
   2: {
   3:     string data = Encoding.UTF8.GetString(args.Buffer, 0, args.BytesTransferred);
   4:  
   5:     IEnumerable<Sample> samples = this.GetSamples(ref data);
   6:  
   7:     Array.Clear(args.Buffer, 0, 1024);
   8:  
   9:     if (data.Length > 0)
  10:     {
  11:         byte[] bytes = Encoding.UTF8.GetBytes(data);
  12:         Array.Copy(bytes, args.Buffer, bytes.Length);
  13:         args.SetBuffer(bytes.Length, 1024 - bytes.Length);
  14:     }
  15:     else
  16:         args.SetBuffer(0, 1024);
  17:  
  18:     if (this.Socket.Connected)
  19:         this.Socket.ReceiveAsync(args);
  20:  
  21:     this.Update(samples);
  22: }

The method peek up the received data and then calls again the ReceiveAsync method of the connection to make again the channel ready to receive other informations. Then the Update method is called to update the properties binded to the view.

The code is simple and obviously it need some additional check, as an example it needs to verify the communication errors that here are swallowed. I hope it shows, once again, how reactive extension can help you to simplify the consumption of asynchronous streams.

Taking advantage of combining different streams using Reactive Extension's:

2011-04-04T16:18:45+01:00 by Andrea Boschin

One interesting feature of Reactive Extensions is the combining of Observables. There are a number of extension methods made to combine two or more streams; Amb, Concat, SelectMany, Merge, Zip, CombineLatest, all these methods are made to take, multiple and non necessarily omogeneous, streams and combine them in a unique resulting stream based on different rules. Here a brief resume of the rules applied from every method

Amb returns the stream that start providing values by first
Concat chain two streams one to the end of the other and create a single output
SelectMany Returns every value from the second stream for each value from the first
Merge returns the two streams merged basing of when each source returns its value
Zip returns values from one stream paired with values from another, only when a couple is available.
CombineLatest Combine two streams returning always the latest from both, for each occurrence of a value.

 

Understanding the meaning of each method is really difficult if you do not make some simple experiment, but this is out of the scope of this post. Now I would like to show the meaning of "combining two streams" with a real example that show how a little change in the previous mouse trail example can give a great difference in terms of functions.

In my last example I used the TrailWithCount and TrailWithTime methods to catch MouseMove events to draw a polyline on the plugin that il the trail of the mouse pointer. In the example you have seen the trail shortens while the mouse was moving but when the mouse stops also the trail stops. Now I want to change the example to let the trail shorten to zero length when the mouse stops moving.

To achieve this result I need to have a timer that continues to record the current position for the mouse when it stops. For this purpose I can use the static method Obsevable.Interval(timespan) that is able to generate a stream of events at the given interval of time. Here is the two lines I have to add to the previous example.

   1: Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
   2:     ev => new MouseEventHandler(ev),
   3:     ev => this.LayoutRoot.MouseMove += ev,
   4:     ev => this.LayoutRoot.MouseMove -= ev)
   5:     .CombineLatest(Observable.Interval(TimeSpan.FromMilliseconds(25)), (a, b) => a)
   6:     .ObserveOnDispatcher()
   7:     .Select(o => o.EventArgs.GetPosition(this.LayoutRoot))
   8:     .TrailWithCount(100)
   9:     .Subscribe(DrawLine);

the CombineLatest method gets events from the mouse and from the time interval (this regularly every 25 milliseconds) and using the selector lambda it takes from the combined stream only the mouse events. Every time an interval expire the combined value will contain an integer (the number of intervals from the start) and the latest mouse event. When the mouse stops moving the stream from the MouseMove also stops to provide values but the CombineLatest method will replicate the latest value taken for every interval elapsed. So the trail will be feeded with the latest position and the visual effect will be the shorten of the trail until it reaches the current position of the mouse pointer.

The ObserveOnDispatched method is required because the Observable.Interval method implies the use of a separate thread so when we get the values we are in this thread and we need to marshall back to the UI thread. This method does the trick. Here is the result:

Get Microsoft Silverlight