Azure API and Logic Apps

Last monday we did a little event where we talked about some new exciting stuff that was announced on Build San Fransisco. I had a talk about API and Logic apps in Azure, which can be used for creating "microservices" apps.

As Martin Fowler defines it :the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API (see more here)

My slides can be found here :



API Apps for web, mobile and logic apps.pdf (764.1KB)

New version of U2U CAML Query Builder

The original U2U CAML Query Builder has been around for many years, and is being used by many SharePoint professionals. So we thought it was time for giving it some small changes, and bringing it to version 4.2.0.0. The query builder now uses CSOM for connecting to SharePoint, and it also allows connecting to Office365 now.
Picture1
Next to these changes we also have two smaller changes:
  1. The different types of queries that can be created has been reduced to two for simplification.
    Picture2
  2. We added some tabs for directly copying Server- and Client-side code:
    Picture3

There you go, I hope you’ll enjoy it as much as previous versions.We’ll try to get you some more CAML query goodies later ! For now: you can find the Query Builder at http://u2u.be/software.

Creating updatable Live Tile from A to Z (part 2)

At last, part 2 of this blogpost. In part 1, we created an updatable Live Tile. We still need to update it with a Background task. We start by adding a Windows Phone Scheduled Task Agent, which is a projecttype added with the devtools for the Mango-version. This type allows you to ask tasks to be performed in the background. By default the task will run every 30 minutes (It can take longer depending on the memorypressure of the device). In here you can have an override of OnInvoke, that should perform the actual backgroundtask of your app.

The control (Indicator) whom I am using for creating a WriteableBitmap with, needs to be accessible from within the app ánd from within the backgroundtask. Since the app already needs a reference to the BackgroundTask, we cannot create a reference in the opposite direction. So we need to move the Indicator into a separate class-library.

You’ll probably see that this works quiet nicely, until all of a sudden your solution no longer builds. In your code all of the Indicator-properties seems to be absent. I presume it’s a bug in Visual Studio, but from time to time the BuildAction-property for Indicator.xaml changes, which prevents your solution from building. If it happens to you: change it back to “Page” :

image

Let’s do a little update of the tile we created :

   1:  Deployment.Current.Dispatcher.BeginInvoke(() =>
   2:              {
   3:                  Indicator indicator = new Indicator();
   4:   
   5:                  indicator.KPI1Brush = new SolidColorBrush(Colors.Magenta);
   6:                  indicator.KPI2Brush = new SolidColorBrush(Colors.Orange);
   7:                  indicator.KPI3Brush = new SolidColorBrush(Colors.Red);
   8:                  indicator.KPI4Brush = new SolidColorBrush(Colors.Yellow);
   9:   
  10:                  indicator.Measure(new Size(173, 173));
  11:                  indicator.Arrange(new Rect(0, 0, 173, 173));
  12:   
  13:   
  14:                  string indic = "/Shared/ShellContent/indicator.jpg";
  15:                  WriteableBitmap bm = new WriteableBitmap(indicator, null);
  16:                  IsolatedStorageFile isolated = IsolatedStorageFile.GetUserStoreForApplication();
  17:                  if (isolated.FileExists(indic))
  18:                  {
  19:                      isolated.DeleteFile(indic);
  20:                  }
  21:                  IsolatedStorageFileStream stream = isolated.CreateFile(indic);
  22:                  bm.SaveJpeg(stream, 50, 50, 0, 100);
  23:                  stream.Flush();
  24:                  stream.Close();
  25:   
  26:                  ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
  27:                  ShellTileData data = new StandardTileData()
  28:                  {
  29:                      BackContent = "Sober at 18:23",
  30:                      BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/indicator.jpg", UriKind.Absolute),
  31:                      BackTitle = "0.123"
  32:                  };
  33:   
  34:                  tile.Update(data);
  35:              });

 

This is of course very similar to the code in the first part of this blogpost. You can see that in here we also store the bitmap in isolated storage. The nice thing here is that the isolated storage is being shared between the backgroundtask, and the application for which you create the task. So it could also be used for transferring data from the app to the task.

Actually we’re changing stuff on the GUI Thread from a background thread, that’s why we need the dispatcher-object here.

One little problem remains : I would like to set one of the KPI-colors of my indicator to the PhoneForeGroundColor. In the app I do as such :

new SolidColorBrush((Color)App.Current.Resources["PhoneForegroundColor"]);

 

(Or use “PhoneForegroundBrush” for getting a Brush-object) But what to do in the BackgroundTask, since I do not have access to the App-class in there ? No problem: you can also access the system-resources through objects inheriting from FrameworkElement :

new SolidColorBrush((Color) indicator.Resources["PhoneForegroundColor"]);

 

Cool: ready to deploy !

Creating updatable Live Tiles from A to Z (part 1)

Something I haven’t found on the webs, is a nice overview of how to create updatable live tiles. Sure, you can gather all the data, but all the do’s and gotcha’s in one article would be nice. So I decided to get everything together myself.

OK: here’s the scenario. We need an app that visually shows information. Think about e.g. the mail-app that shows how many unread mails you have. Or a very nice one: Amazing Weather, which shows current weather conditions, and predictions. In our app we’ll show four arbitrary KPI’s on the tile, which will be updated in the background.

Step 1 : simple Tile

Your application can have one or several tiles on the start page( several if you implemented Deep link in your app), which can be reached by using the ShellTile.ActiveTiles collection. In my example there’s no deep link, so I should always get one tile, or none when not pinned to start. The Tile can be modified by passing it a ShellTileData-object. This way you can change front (Title, Count, BackgroundImage) and back (BackTitle, BackContent, BackBackgroundImage) of the tile. I will change the time whenever my app closes or deactivates :

   1:  ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
   2:  if (tile!=null)
   3:  {
   4:      ShellTileData data = new StandardTileData()
   5:      {
   6:          Title = "12345",
   7:          Count = 5,
   8:          BackContent = "Some message...",
   9:          BackBackgroundImage = new Uri("http://mw2.google.com/mw-panoramio/photos/medium/33672781.jpg"),
  10:          BackTitle = "ABCDEF"
  11:      };
  12:   
  13:      tile.Update(data);
  14:  }

 

This gives me following result :

Front : Back :
1 2

Although this can already be handy for some scenario’s, it’s not enough. The count does not appear like in the mail-hub. Unfortunately. And I could show my KPI’s with text, but my Tile will be full of text, and maybe I’ll have more text than can fit on the Tile.

Step 2 : not so simple Tile

Remember my blogpost about saving pictures to the PicturesHub (over here) ? In there I showed you can create bitmapimages from any control. This is also what we’ll be doing when creating our tile-images. I start by creating a usercontrol. Best is to give it height and width equal to 173. This is the height/width for the tile. This will allow you to easily create your tile in a WYSIWYG-way. The usercontrol simply shows my four KPI’s by using “Trafficlights”, showing red, orange or green. I will also add white (or black if the light theme is being used) for “disaster”. Let’s start creating our usercontrol :

image
   1:  <UserControl x:Class="PhoneApp1.Indicator"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:      mc:Ignorable="d"
   7:      FontFamily="{StaticResource PhoneFontFamilyNormal}"
   8:      FontSize="{StaticResource PhoneFontSizeNormal}"
   9:      Foreground="{StaticResource PhoneForegroundBrush}"
  10:      d:DesignHeight="480" d:DesignWidth="480" Height="173" Width="173">
  11:   
  12:      <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneAccentBrush}">
  13:   
  14:          <Grid.RowDefinitions>
  15:              <RowDefinition Height="2*" />
  16:              <RowDefinition Height="*" />
  17:          </Grid.RowDefinitions>
  18:          <Grid.ColumnDefinitions>
  19:              <ColumnDefinition Width="2*" />
  20:              <ColumnDefinition Width="*" />
  21:          </Grid.ColumnDefinitions>
  22:          <Rectangle Name="KPI1Indicator" Stroke="{StaticResource PhoneBorderBrush}" StrokeThickness="2" Fill="Red" Margin="80,80,10,10" RadiusX="20" RadiusY="20" />
  23:          <Rectangle Name="KPI2Indicator" Grid.Column="1" Stroke="{StaticResource PhoneBorderBrush}" StrokeThickness="2" Fill="Green" Margin="3,80,30,10" RadiusX="20" RadiusY="20" />
  24:          <Rectangle Name="KPI3Indicator" Grid.Row="1" Stroke="{StaticResource PhoneBorderBrush}" StrokeThickness="2" Fill="Orange" Margin="80,3,10,30" RadiusX="20" RadiusY="20" />
  25:          <Rectangle Grid.Column="1" Grid.Row="1" Name="KPI4Indicator" Stroke="{StaticResource PhoneBorderBrush}" StrokeThickness="2" Fill="Yellow" Margin="3,3,30,30" RadiusX="20" RadiusY="20" />
  26:      </Grid>
  27:  </UserControl>

 

The four KPI-indicators need to be exposed to the outside word, so let’s add some properties for that :

   1:  public Brush KPI1Brush
   2:  {
   3:      get { return KPI1Indicator.Fill; }
   4:      set { KPI1Indicator.Fill = value; }
   5:  }
   6:   
   7:  public Brush KPI2Brush
   8:  {
   9:      get { return KPI2Indicator.Fill; }
  10:      set { KPI2Indicator.Fill = value; }
  11:  }
  12:   
  13:  public Brush KPI3Brush
  14:  {
  15:      get { return KPI3Indicator.Fill; }
  16:      set { KPI3Indicator.Fill = value; }
  17:  }
  18:   
  19:  public Brush KPI4Brush
  20:  {
  21:      get { return KPI4Indicator.Fill; }
  22:      set { KPI4Indicator.Fill = value; }
  23:  }

 

When closing/deactivating the app, I will set the KPI-colors, and use this controls as image for the back of my tile. First, setting the colors:

   1:  Indicator indicator = new Indicator();
   2:   
   3:  indicator.KPI1Brush = new SolidColorBrush(Colors.Black);
   4:  indicator.KPI2Brush = new SolidColorBrush(Colors.Blue);
   5:  indicator.KPI3Brush = new SolidColorBrush(Colors.Cyan);
   6:  indicator.KPI4Brush = new SolidColorBrush(Colors.Green);

And then making a WriteableBitmap with it :

indicator.Measure(new Size(173, 173));
indicator.Arrange(new Rect(0, 0, 173, 173));

WriteableBitmap bm = new WriteableBitmap(indicator, null);

The Measure and Arrange-stuff is for making the control fit into a 173 by 173 square. Finally I need to save my image to Isolated Storage. Inside isolated storage I can store things in the Shared/Shellcontent-folder. This will also make it accessible by my tiles (info here).

   1:  string indic = "/Shared/ShellContent/indicator.jpg";
   2:   
   3:  IsolatedStorageFile isolated = IsolatedStorageFile.GetUserStoreForApplication();
   4:  if (isolated.FileExists(indic))
   5:  {
   6:      isolated.DeleteFile(indic);
   7:  }
   8:  IsolatedStorageFileStream stream = isolated.CreateFile(indic);
   9:  bm.SaveJpeg(stream, 173, 173, 0, 100);
  10:  stream.Flush();
  11:  stream.Close();

 

And finally, I update my Tile to show the image from isolated storage :

   1:  ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
   2:  if (tile!=null)
   3:  {
   4:      ShellTileData data = new StandardTileData()
   5:      {
   6:          Title = "12345",
   7:          Count = 5,
   8:          BackContent = "Some message...",
   9:          BackBackgroundImage = 
  10:              new Uri("isostore:/Shared/ShellContent/indicator.jpg", UriKind.Absolute),
  11:          BackTitle = "ABCDEF"
  12:      };
  13:   
  14:      tile.Update(data);
  15:  }

and there you go :

1

In next blogpost I’ll tell you about updating the tile with a backgroundtask, which also has some gotcha’s you need to know.


>

Using a Sterling-database in Windows Phone as alternative to SQL CE

I you remember my blogpost from a very long time ago, I wrote about using SQL CE with Windows Phone (you can find it here). SQL CE can be queried with LINQ to SQL, making it interesting for storing relational data. Recently I came in contact with the Sterling-database (check it here), an Object-database which can be used in .NET, Silverlight and Windows Phone ! You can add “SterlingPhone” to your project by using NuGet. Just like SQL CE I can use Sterling for storing data in Isolated Storage.

I’ll show you how to use it with a “fake” Northwind-database, but it can also be used for persisting full Viewmodels when using MVVM. In my fake Northwind-database I will use Products and Categories, so I simply start by creating classes for these two entities :

   1:  public class Product
   2:  {
   3:      public int ProductId { get; set; }
   4:   
   5:      public string ProductName { get; set; }
   6:   
   7:      public double? UnitPrice { get; set; }
   8:   
   9:      public Category Category { get; set; }
  10:  }
  11:   
  12:  public class Category 
  13:  {
  14:      public int CategoryId { get; set; }
  15:   
  16:      public string CategoryName { get; set; }
  17:   
  18:      public List<Product> Products { get; set; }
  19:  }

 

These classes are pure and simple POCO-classes, no specific classes to inherit from or a bunch of attributes to use.

Second step is to create our “database-class”, which inherits from BaseDatabaseInstance :

public class FakeNorthWindDatabase : BaseDatabaseInstance

In here I will register my tables by overriding RegisterTables :

protected override System.Collections.Generic.List<ITableDefinition> RegisterTables()
{
    return new List<ITableDefinition>() 
    {
        this.CreateTableDefinition<Product,int>(p=>p.ProductId)
            .WithIndex<Product,Category,int>("IX_ProductCategory",p=>p.Category),
        this.CreateTableDefinition<Category,int>(c=>c.CategoryId)
    };
}

In here I create the table Category and Products, which are respectively using the CategoryId and ProductId-properties as identifiers. The WithIndex-option creates a relationship between these two entities.

This database also needs to be registered. I do that in the Application_Launching:

   1:  private SterlingEngine engine;
   2:  private SterlingDefaultLogger logger;
   3:   
   4:  public static ISterlingDatabaseInstance DB { get; set; }
   5:   
   6:  private void Application_Launching(object sender, LaunchingEventArgs e)
   7:  {
   8:      InitDB();
   9:  }
  10:   
  11:  private void InitDB()
  12:  {
  13:      engine = new SterlingEngine();
  14:      engine.SterlingDatabase.RegisterSerializer<DefaultSerializer>();
  15:      engine.Activate();
  16:   
  17:      DB = engine.SterlingDatabase.RegisterDatabase<FakeNorthWindDatabase>();
  18:      FakeNorthWindDatabase.Init(DB);
  19:  }

 

One of the things we need to do is to specify which serializer will be used for writing and reading data. At this moment we only have the DefaultSerializer and AggregateSerializer, but you could create your own classes here, as long as they inherit from BaseSerializer.

At the end I call the init-method of the FakeNorthWindDatabase, which I implemented as follows :

   1:  internal static void Init(Wintellect.Sterling.ISterlingDatabaseInstance DB)
   2:  {
   3:      if (!DB.Query<Category,int>().Any())
   4:      {
   5:          Category c1 = new Category() { CategoryId=1, CategoryName = "Beverages"};
   6:          Category c2 = new Category() { CategoryId = 2, CategoryName = "Cheese" };
   7:          Category c3 = new Category() { CategoryId = 3, CategoryName = "Seafood" };
   8:   
   9:          Product p11 = new Product() { ProductId = 1, ProductName = "WestVleteren 12",
  10:              UnitPrice = 3, Category = c1 };
  11:          Product p12 = new Product() { ProductId = 2, ProductName = "Rochefort 10", 
  12:              UnitPrice = 3, Category = c1 };
  13:          Product p13 = new Product() { ProductId = 3, ProductName = "Maredsous 8", 
  14:              UnitPrice = 2.5, Category = c1 };
  15:   
  16:          Product p21 = new Product() { ProductId = 4, ProductName = "Maredsous", 
  17:              UnitPrice = 3, Category = c2 };
  18:          Product p22 = new Product() { ProductId = 5, ProductName = "Gouda", 
  19:              UnitPrice = 3, Category = c2 };
  20:          Product p23 = new Product() { ProductId = 6, ProductName = "Cambozola", 
  21:              UnitPrice = 2.5, Category = c2 };
  22:   
  23:          Product p31 = new Product() { ProductId = 7, ProductName = "Shrimps", 
  24:              UnitPrice = 3, Category = c3 };
  25:          Product p32 = new Product() { ProductId = 8, ProductName = "Tuna Fish", 
  26:              UnitPrice = 3, Category = c3 };
  27:          Product p33 = new Product() { ProductId = 9, ProductName = "Calamares", 
  28:              UnitPrice = 2.5, Category = c3 };
  29:   
  30:          DB.Save(c1);
  31:          DB.Save(c2);
  32:          DB.Save(c3);
  33:   
  34:          DB.Save(p11);
  35:          DB.Save(p12);
  36:          DB.Save(p13);
  37:          DB.Save(p21);
  38:          DB.Save(p22);
  39:          DB.Save(p23);
  40:          DB.Save(p31);
  41:          DB.Save(p32);
  42:          DB.Save(p33);
  43:      }
  44:  }

This code first checks if there is already categories present, and if not starts filling the database with some sample-data. We can now use our data: let’s simply show the name of a Category. The Sterling-database has a load-function that can be passed the key-value of the entity to find :

   1:  private void button1_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      Category c= App.DB.Load<Category>(1);
   4:      MessageBox.Show(c.CategoryName);
   5:  }

Simple. Retrieving a list is also simple :

listBox1.ItemsSource = App.DB.Query<Category, int>().Select(c => c.LazyValue.Value);

 

The select-method uses a delegate that takes a TableKey<Category,int> and returns an object, in this case the Category-entity. By using LINQ I can get the products for a specific category :

int catId = Convert.ToInt32(NavigationContext.QueryString["cat"]);
listBox1.ItemsSource = (from p in App.DB.Query<Product, int>()
                        where p.LazyValue.Value.Category.CategoryId == catId
                       select p.LazyValue.Value).ToList();

 

Let’s add a new Category and product :

   1:  Category c = new Category()
   2:  {
   3:      CategoryId = 4,
   4:      CategoryName = "Condiments"
   5:  };
   6:   
   7:  Product p = new Product()
   8:  {
   9:      ProductId = 10,
  10:      ProductName = "Aniseed Syrup",
  11:      UnitPrice = 12.2,
  12:      Category = c
  13:  };
  14:   
  15:  App.DB.Save<Product>(p);

Saving the product also saves the category. Save checks the Id-field to know if it should do an update or an insert. Unfortunately there’s no autonumber-functionality, but Sterling also allows me to create triggers, with which I could create autonumber-functionality myself.

This blogpost just scratches the surface of Sterling, there’s lots more fun stuff you can do with it, so check it out if you need to store persistant data.




Using Reactive extensions for feeding test sensor-readings in Windows Phone

An interesting technology you might have heard of is Reactive Extension (MSDN Rx Site). It’s available for different types of applications, although  you may need to add the necessary assemblies through NuGet. But in WP7.5 it’s included in the SDK. The only thing you need are references to Microsoft.Phone.Reactive and System.Observable.  Let’s start with a very simple scenario : simulating the PositionChanged-event of the GeoCoordinateWatcher. I know that the Mango-emulator allows me to simulate Geographical position, but it’s a nice starting point.

My application consists out of a very simple Page which shows a Bing mapcontrol. I set the Zoomlevel to 10, and we’re set to go. The code is fairly simple :

   1:  private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
   4:      watcher.MovementThreshold = 1;
   5:      watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
   6:      
   7:      watcher.Start();
   8:  }
   9:   
  10:  void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
  11:  {
  12:      map1.Dispatcher.BeginInvoke(()=> map1.Center = e.Position.Location);
  13:  }

 

Now let’s try to simulate some changes in our position: Let’s travel from South England to France, passing Dover and Calais. Let’s start by creating a simple function that gives me back an GeoPositionEventArgs every 50 ms :

   1:  #if DEBUG
   2:  static double l = 0;
   3:   
   4:  private static IEnumerable<GeoPositionChangedEventArgs<GeoCoordinate>> GetLocations() 
   5:  {
   6:      while (true)
   7:      {
   8:          System.Threading.Thread.Sleep(50);
   9:          l += .001;
  10:   
  11:          yield return new GeoPositionChangedEventArgs<GeoCoordinate>
  12:              (new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, new GeoCoordinate(51, l)));
  13:      }
  14:  }
  15:  #endif

Now let’s create a Thread that calls this functions, and uses Rx for feeding the eventargs to the eventhandler :

   1:  private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
   4:      watcher.MovementThreshold = 1;
   5:      watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
   6:   
   7:      #if DEBUG
   8:      System.Threading.Thread thr = new System.Threading.Thread(() =>
   9:      {
  10:          var test = GetLocations().ToObservable();
  11:          test.Subscribe(ea => watcher_PositionChanged(null, ea));
  12:      });
  13:   
  14:      thr.Start();
  15:      #endif
  16:      
  17:      watcher.Start();
  18:  }

 

The ToObservable-function turns my IEnumerable<T> into an IObservable<T>. The Subscribe-function binds it with the eventhandler. Run the app (in debug-mode, of course), and you’ll see the map slowly moving East passing from England to France.

image

Now let’s try to use the same concept with the Accelerometer. I create a simple page with three TextBlock-controls for displaying the X,Y and Z-components of my accelaration. In here we’ll have to do similar stuff with SensorReadingEventArgs<AccelerometerReading>. In AccelerometerReading I need to set the Acceleration-property which is of type Vector3 (with X,Y,Z). The problem that arrises here is that the setter of Accelartion is declared as internal, so I cannot use this from my code. The solution can be found at Microsoft Patterns and Practices site, which has some recipes for creating alternatives for the sensor-classes (here). Instead of the AccelerometerReading-class I can use AccelerometerSensorReading-class and the SettableAccelerometerSensorReading-class. The name of the latter already describes it : it will allow me to set the Acceleration-property. Let’s have a look at the result :

   1:  private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
   2:  {
   3:      AccelerometerAdapter acc = new AccelerometerAdapter();
   4:      acc.TimeBetweenUpdates = TimeSpan.FromSeconds(1);
   5:   
   6:      acc.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerSensorReading>>(acc_CurrentValueChanged)
   7:      acc.Start();
   8:   
   9:  #if DEBUG
  10:      System.Threading.Thread thr = new System.Threading.Thread(() => 
  11:      {
  12:          var test = GetReadings().ToObservable();
  13:          test.Subscribe(ea => acc_CurrentValueChanged(null, ea));
  14:          });
  15:   
  16:      thr.Start();
  17:  #endif
  18:  }
  19:   
  20:  void acc_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerSensorReading> e)
  21:  {
  22:      ContentPanel.Dispatcher.BeginInvoke(() => 
  23:      {
  24:          textBlock1.Text = e.SensorReading.Acceleration.X.ToString();
  25:          textBlock2.Text = e.SensorReading.Acceleration.Y.ToString();
  26:          textBlock3.Text = e.SensorReading.Acceleration.Z.ToString();
  27:      });            
  28:  }
  29:   
  30:  #if DEBUG
  31:   
  32:  static float f = 0f;
  33:  public static IEnumerable<SensorReadingEventArgs<AccelerometerSensorReading>> GetReadings()
  34:  {
  35:      while (true)
  36:      {
  37:          System.Threading.Thread.Sleep(500);
  38:          var acc = new SettableAccelerometerSensorReading();
  39:          acc.SetAcceleration(new Vector3(f, 0f, 0f));
  40:          f += .1f;
  41:          if (f > Math.PI)
  42:          {
  43:              f = (float)-Math.PI;
  44:          }
  45:          var reading = new SensorReadingEventArgs<AccelerometerSensorReading>();
  46:   
  47:          yield return new SensorReadingEventArgs<AccelerometerSensorReading>() { SensorReading = acc }; 
  48:      }
  49:  }
  50:  #endif

 

And there you go. Also tried it with the virtual Motion-sensor, unfortunately I got stuck there. I’m missing a SettableAttitudeReading-class, and I’ve been trying to create it since a few days, but I’m close to giving up. I guess there’s a reason for not having it in the patterns-library.




File IO in Windows 8

Let’s leave Windows Phone for a moment, and let’s have a look at Windows 8. Recently the U2U-team was present at the Microsoft Build-convention in Anaheim, California, where Microsoft unveiled Windows 8. Now, what we saw is still just a preview, but it clearly shows the direction in which Windows is evolving. Have a look at this video, to see Windows 8 in action :

 

The “new style” applications Windows 8 offers are “Metro”-applications (yes, like in Windows Phone Metro style), and these can be made using Xaml and managed code, or even using HTML5 + Javascript. Metro-apps will have to be installed through a marketplace, and are kind of sandboxed (Comparable to Silverlight, but different ;-)  ). One of the effects of this sandboxing is that your options for working with files are limited. You cannot just access any folder on your machine ! Unfortunately you’re also unable to use Isolated Storage. So what can you use ? Let’s start by writing info into the “Local Folder”.

Windows.Storage.ApplicationData appData = Windows.Storage.ApplicationData.Current;
 
StorageFile file = await appData.LocalFolder.CreateFileAsync("EmployeeList.u2u");
Windows.Storage.Streams.IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite);

 

No ordinary File here, but a StorageFile which I have to open to write in. The IRandomAccessStream I get back gives me the possibility to create an input- (for reading) or output-stream (for writing).

IOutputStream output = stream.GetOutputStreamAt(0);

 

And then I got stuck. The IOutputStream gives me a WriteAsync-function, but it ask me for an IBuffer-object. How to write data ? Luckily there’s already some MSDN-documentation available. That tells me to use a DataWriter which takes the IOutputStream as a constructor-argument.

DataWriter writer = new DataWriter(output);
writer.WriteString("HERE GOES DATA");
output.FlushAsync();

 

Not there yet ! The code I wrote starts fro; the assumption that File IO is much like the “ordinary” file IO: flush the stream and done. In Metro we have to ”commit” the data in the writer, and I have to start the flushing, so this is the working code :

   1:  DataWriter writer = new DataWriter(output);
   2:  writer.WriteString("HERE GOES DATA");
   3:   
   4:  await writer.StoreAsync();
   5:  output.FlushAsync().Start();    
   6:  statusTxt.Text = "File Saved";

 

They could have made it simpler Smile.
By localfolder I assumed the bin/debug-folder. Nothing there. It seems my file is located in C:\Users\michael\AppData\Local\Packages\d64899f1-9800-470a-9cb3-fa89210f4941_qs0a8q7rnpy8j\LocalState.

How about reading the file ? Well, simply reverse your writing-logic (writer becomes reader, output becomes input, store becomes load, …)

   1:  Windows.Storage.ApplicationData appData = Windows.Storage.ApplicationData.Current;
   2:   
   3:  var file = await appData.LocalFolder.GetFileAsync("EmployeeList.u2u");
   4:  Windows.Storage.Streams.IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
   5:   
   6:  IInputStream input = stream.GetInputStreamAt(0);
   7:   
   8:  DataReader reader = new DataReader(input);
   9:   
  10:  var size = stream.Size;
  11:  await reader.LoadAsync((uint)size);
  12:  var data = reader.ReadString((uint)size);

 

There you go!

What about other folders than the “local” ? The KnownFolders=clqss gives me access to following locations :

  • Documents Library
  • Home Group
  • Media Server Devices (DLNA – Digital Living Network Alliance Devices, sounds interesting)
  • MusicLibrary
  • Pictures Library
  • Removable Devices
  • Videos Library

Let’s change the first 2 lines of my writing-code for using the documents library :

StorageFolder doclib = Windows.Storage.KnownFolders.DocumentsLibrary;
 
StorageFile file = await doclib.CreateFileAsync("EmployeeList.u2u");

 

As soon as you start running your code, it will fail on the first line (no exception though, simply stops). That’s because you explicitly have to give the app the capability to access the Document library. Double-clicking on Package.appxmanifest allows you to do that :

image

Still: this time your app will stop on the second line. You also need to associate your app with the u2u-fileextension. This is also done in the appxmanifest-file in the declarations-tab where we add a filetype association declaration :

image

There you go: the app works and saves my u2u-file in the doclibrary.

Creating WP7 prototypes with Sketchflow

With the upcoming release of Windows Phone Mango, you can create prototypes for Phone apps with Sketchflow. For people not knowing Sketchflow : it allows you to create prototypes that look like they have been drawn. When you present a “normal” prototype to a customer you get conversations like this :

Nice protoype, how long before you can deliver us the final product ?

I estimate we can deliver within 4 months.

What ? You created this prototype in just 3 days, it looks like it’s almost finished. How can it possibly take 4 months for completing ?

A sketchflow prototype looks more “unfinished”. It’s not new, it has been around for WPF and silverlight, but you can now also get the projecttemplate for WP7 for using in Blend. Just go to http://wp7sketchflow.codeplex.com/, download and install. Beware : you can only use this thing if you have the full paid version of Blend. The one you get for free with the phone developers tool will not do.

OK. Let’s open up Blend and create a Windows Phone SketchFlow application :

image

This project directly creates some an empty screen for my app  and a fake start-up screen:

image

I also get an overview how I can move (“Flow”) between the different screens:

image

I created a little prototype for an application I sometimes create during WP7-courses : a complaints-application for my city (the well-know megacity Serskamp in Belgium). This application allows me to signal stuff like defective traffic lights a.o. I also need to be able to add a location (GPS) and a picture, and to track my filed complaints. I’m not going to create the app itself now, but just the screens.

I start by adding a Panorama on my start screen. This thing automatically gets 2 Panorama-items. The design of my item looks like this :

image image

For the data I created a demo-datasource in the data-tab:

image 

got some trouble for designing the second Panorama-item. Unlike Visual Studio, in which you simply have to select a Panorama-item for making it the active one, there’s no such thing in Blend. Or at least I didn’t find it. The only thing I could do was temporary setting the visibility of the other items to collapsed.

Inside the Flow-panel I can select to add a new Connected screen. This way I create a screen for the follow-up of my complaints, and one for setting the location. I also create connections for returning to Screen 1, and remove the connection from my new screens to Search and AppList.

image

The Follow-up screen looks like this :

image

For finishing I also change the start-screen, and I’m done.

image

Now I’ve finished my SketchFlow-prototype, there’s 2 thing I can do : print it, or run it. In the File-menu you have an option for exporting to Word. This will export all your designs and add a table of contents :

WindowsPhonePrototype2.doc (1,28 mb) 

Creating a SketchFlow-prototype is essentially creating a Silverlight-application. This gives you a way of “running” the app, so you can demonstrate it to your customer (see video) :

 

 

Is that cool, or what ?

 

 



The return of SQL CE !

After playing a few weeks with the Mango-beta, I’m even more convinced that the Windows Phone 7 simply is the best smartphone available. Driving in your car, receiving a text-message, and suddenly a voice over Bluetooth  asks me if the message should be read! And after the message has been read, it asks if I would like to dictate an answer (or call). How cool is that ? (unfortunately only in English for the moment, so when trying to dictate in Dutch, you get funny results ).

One of the things that Mango brings is SQL Server CE. I remember using this on Windows Mobile, when you had to use stuff like SqlCeConnection, SqlCeCommand, etc… It seems that these classes are not existing on Mango, but of course we have Linq to SQL we can use. Using IsolatedStorageFile’s for storing data is nice, but having a “real” database for storing relational data is nicer. Still, during my experiment I saw that there are a few things missing to make life easier. It’s still in beta of course, so hopefully it will get added in the near future.

I wanted to do a little trial showing the products and Categories out of the NorthWind-database. I decided to use SQL Integration Services for creating a SQL CE database for me, copying the needed data. Unfortunately this is not possible for CE. I needed to create the database and the tables myself. In the beta-version of Mango developer-tools it is yet impossible to select a SQLCE-file for item to add. I simply created it in a dummy console-app, and then copied it into my WP7-application. Double clicking on the sdf-file opens up the designer.

image

Adding a table is easy: Right-click the Tables-folder, select “Create Table” and you can start designing. This is what I created :

image

Specifying the Primary Key and the relationship between Products and Categories can be created by calling the table properties:

image

So far for the database structure. Copying the data from the “normal” Northwind to my CE-tables can be done through SQL Integration services. Now what about the LINQ to SQL classes ? No way of adding such an item in my project. The way to go, is like in the beginning of LINQ: use SQLMetal (You’ll find it here : C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin). The following command generates the necessary code:

Sqlmetal /code:NorthWindCE.cs Northwind.sdf

 

The generated code look nice, but if your looking for any navigation-properties: nowhere to find…

Next roadblock: I can only access databases stored in isolatedstorage. Makes sense, although it would be nice to be able to share data over multiple apps. Since there is no direct way of adding files for IsolatedStorage in VisualStudio, I wrote a bit of code for copying my sdf-file (which has been added as a resource) to IsolatedStorage:

   1:  private void CheckIsolatedStorageDb()
   2:  {
   3:      var storage = IsolatedStorageFile.GetUserStoreForApplication();
   4:      if (!storage.FileExists("NorthWind.sdf"))
   5:      {
   6:          Uri uri = new Uri("SQLTest;component/NorthWind.sdf",UriKind.Relative);
   7:          StreamResourceInfo info = App.GetResourceStream(uri);
   8:   
   9:          if (info!=null)
  10:          {
  11:              Stream stream = info.Stream;
  12:              BinaryReader reader = new BinaryReader(stream);
  13:              byte[] buffer = new byte[stream.Length];
  14:              reader.Read(buffer, 0, Convert.ToInt32(stream.Length));
  15:              reader.Dispose();
  16:   
  17:              IsolatedStorageFileStream iStream= storage.CreateFile("NorthWind.sdf");
  18:              iStream.Write(buffer, 0, buffer.Length);
  19:              iStream.Flush();
  20:              iStream.Dispose();
  21:              stream.Dispose();
  22:          }
  23:      }
  24:  }

 

I call this function on Application_launch, and my sdf-file gets copied.  From now on I can start using my db, using LINQ. Let’s start by adding a listbox to our MainPage like this:

<ListBox DisplayMemberPath="ProductName" ItemsSource="{Binding}" />

 

Code looks like this :

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    db = new NorthWind("Data Source=isostore:/NorthWind.sdf");
 
    this.DataContext = from p in db.Products
                       where p.UnitPrice < 20
                       select p;    
}

As you can see, I provide a connectionstring pointing to Isolated storage, binding the datacontext to some LINQ-statement, and voila.

Now what about navigating between categories and products ? First I extend my SQLmetal-generated code with these (copied these by generating code for the “big” Northwind) :

In Products:

   1:  private EntityRef<Categories> _Category;
   2:   
   3:  [global::System.Data.Linq.Mapping.AssociationAttribute(Name = "Category_Product", Storage = "_Category",
   4:      ThisKey = "CategoryID", OtherKey = "CategoryID", IsForeignKey = true)]
   5:  public Categories Category
   6:  {
   7:      get
   8:      {
   9:          return this._Category.Entity;
  10:      }
  11:      set
  12:      {
  13:          Categories previousValue = this._Category.Entity;
  14:          if (((previousValue != value)
  15:                      || (this._Category.HasLoadedOrAssignedValue == false)))
  16:          {
  17:              this.SendPropertyChanging();
  18:              if ((previousValue != null))
  19:              {
  20:                  this._Category.Entity = null;
  21:                  previousValue.Products.Remove(this);
  22:              }
  23:              this._Category.Entity = value;
  24:              if ((value != null))
  25:              {
  26:                  value.Products.Add(this);
  27:                  this._CategoryID = value.CategoryID;
  28:              }
  29:              else
  30:              {
  31:                  this._CategoryID = default(Nullable<int>);
  32:              }
  33:              this.SendPropertyChanged("Category");
  34:          }
  35:      }
  36:  }

And in Categories:

   1:  private EntitySet<Products> _Products;
   2:   
   3:  [global::System.Data.Linq.Mapping.Association(Name="Category_Product", Storage="_Products",
   4:      ThisKey="CategoryID", OtherKey="CategoryID")]
   5:  public EntitySet<Products> Products 
   6:  {
   7:      get { return this._Products; }
   8:      set { this._Products.Assign(value); }
   9:  }

 

  • Let’s now change our MainPage a little: I’ll have two Listboxes this time:
<ListBox DisplayMemberPath="CategoryName" Name="listBox2" ItemsSource="{Binding}" />
<ListBox Grid.Row="1" Name="listBox1" DataContext="{Binding ElementName=listBox2, Path=SelectedItem}"
         DisplayMemberPath="ProductName" ItemsSource="{Binding Products}" />

 

Also set the datacontext to categories this time :

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    db = new NorthWind("Data Source=isostore:/NorthWind.sdf");
 
    this.DataContext = db.Categories;            
}

And thanks to the powers of databinding, I get all products from the category I select.

image

Now I’m already happy to have this in the beta, but I’d like to have some extras in the final version:

  • - Give me an easy way of copying existing structures to my CE database
  • - Get me a way of creating my LINQ to SQL classes from within Visual Studio
  • - Make sure that my Navigation properties are being generated
  • - and give me something, so I can specify files to be directly saved in Isolated Storage. (Some Build Action ? Next to Resource, Content,… also an option IsolatedStorage ?)