Windows 8 Lists: Sizing the list item

This past week, I was helping out at a “hack day” at the Microsoft offices in Downers Grove, IL. One of the attendees had an interesting problem: he wanted the contents of his list to dynamically expand to take up the full width of the ListView. The type of item doesn’t matter, so I picked something with 4 properties for the display that would allow me to exercise core of the issue and nothing more.

public class Class1
{
  public string One { get; set; }
  public string Two { get; set; }
  public string Three { get; set; }
  public string Four { get; set; }
}

This was then bound to a ListView using the following XAML (with a border on each item to help visualize how big the actual template wound up being):

<ListView Name="ListView1">
  <ListView.ItemTemplate>
    <DataTemplate>
      <Border BorderBrush="Red" BorderThickness="2">
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="6*"/>
          </Grid.ColumnDefinitions>
          <TextBlock Grid.Column="0" Text="{Binding One}"/>
          <TextBlock Grid.Column="1" Text="{Binding Two}"/>
          <TextBlock Grid.Column="2" Text="{Binding Three}"/>
          <TextBlock Grid.Column="3" Text="{Binding Four}"/>
        </Grid>
      </Border>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

So far, so good, but when the app displayed the collection of Class1 objects, we saw that the ItemTemplate didn’t extend across the screen.

image

This little item did not do what we wanted it to do, so we thought about what the problem was. A Grid wants to expand to the size of it’s surroundings when not given a limit. The container it was given was one where it was told to size to as big as it needed and no more. As a result, the Grid reported back that it needed to be big enough for the 4 TextBlocks and then was only given that space. Was there a way to go bigger? We looked at the properties and saw one on the ListView called HorizontalContentAlignment, which appeared to let the items align Center, Left, Right, or to Stretch. Stretch usually does good things, so we tried that:

<ListView Name="ListView1" HorizontalContentAlignment="Stretch">

The end result: no change. The screen looked the same as before. At that point, we remembered that we could set the width of the grid manually. Setting the width manually, we were able to achieve the effect, but would still lose any adaptive layout as the screen geometry changed. Still, knowing that the Grid Width property would solve the problem, we only had to find a way to bind the Width of the Grid to the Width of the ListView. On the Grid, we tried binding its width to the Width of ListView 1:

<Grid Width="{Binding ElementName=ListView1, Path=Width}">

Again, no real change. So, we went a bit further. We remembered that we could hook to the SizeChanged event on the ListView and then change a property on the page to feed things. For properties that can be linked to, one can use a combination of DependencyProperty and a value to keep things in sync or implement INotifyPropertyChanged and bind to that value. We tried both paths and found that the DependencyProperty was less code and easier to understand for a control. For this, we added the following to the Page code:

static DependencyProperty ListView1WidthProperty =
  DependencyProperty.Register("ListView1Width", typeof(double), 
  typeof(MainPage), new PropertyMetadata(10));

public double ListView1Width
{
  get { return (double)(GetValue(ListView1WidthProperty)); }
  set { SetValue(ListView1WidthProperty, value); }
}

This code just gave us something to hook into. We then added some code to handle the SizeChanged event on the ListView, which would update the value for ListView1Width:

private void ListView1_SizeChanged(object sender, 
  Windows.UI.Xaml.SizeChangedEventArgs e)
{
  ListView1Width = e.NewSize.Width - 15;
}

This method was hooked up in the XAML as:

<ListView Name="ListView1" SizeChanged="ListView1_SizeChanged">

We then gave the Page the name MyPage in order to allow us to bind to the ListView1Width property. The Grid Width property was now bound as:

<Grid Width="{Binding ElementName=MyPage, Path=ListView1Width}">

The final results were exactly what we wanted:

image

And, as the list was resized to take advantage of other items, like the snap view or portrait view, the resize continued to work.

Assets:

The XAML for this page:

<Page
    x:Class="ColumnsInList.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ColumnsInList"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Name="MyPage" >

  <Grid Name="BigGrid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <ListView Name="ListView1" SizeChanged="ListView1_SizeChanged">
      <ListView.ItemTemplate>
        <DataTemplate>
          <Border BorderBrush="Red" BorderThickness="2">
            <Grid Width="{Binding ElementName=MyPage, Path=ListView1Width}">
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="6*"/>
              </Grid.ColumnDefinitions>
              <TextBlock Grid.Column="0" Text="{Binding One}"/>
              <TextBlock Grid.Column="1" Text="{Binding Two}"/>
              <TextBlock Grid.Column="2" Text="{Binding Three}"/>
              <TextBlock Grid.Column="3" Text="{Binding Four}"/>
            </Grid>
          </Border>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </Grid>
</Page>

C# Code:

// Class1.cs
namespace ColumnsInList
{
  public class Class1
  {
    public string One { get; set; }
    public string Two { get; set; }
    public string Three { get; set; }
    public string Four { get; set; }
  }
}

// MainPage.xaml.cs
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace ColumnsInList
{
  public sealed partial class MainPage : Page
  {
    static DependencyProperty ListView1WidthProperty =
      DependencyProperty.Register("ListView1Width", typeof(double),
      typeof(MainPage), new PropertyMetadata(10));

    public double ListView1Width
    {
      get { return (double)(GetValue(ListView1WidthProperty)); }
      set { SetValue(ListView1WidthProperty, value); }
    }

    public MainPage()
    {
      this.InitializeComponent();

    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
      ListView1.ItemsSource = new ObservableCollection<Class1>(new Class1[] {
              new Class1{One="One1", Two = "Two1", Three ="Three1", Four= "Four1"},
              new Class1{One="One2", Two = "Two2", Three ="Three2", Four= "Four2"},
              new Class1{One="One3", Two = "Two3", Three ="Three3", Four= "Four3"},
              new Class1{One="One4", Two = "Two4", Three ="Three4", Four= "Four4"},
          });
    }

    private void ListView1_SizeChanged(object sender,
      Windows.UI.Xaml.SizeChangedEventArgs e)
    {
      ListView1Width = e.NewSize.Width - 15;
    }

  }
}

Leave a comment

Body Scanners, Fluoroscopes, and the TSA

From the 1920s through about 1960, shoe stores used an amazing device to sell shoes: the fluoroscope. Depending on the year, the reason behind the device changed; it helped you fit the shoe better, it revealed any issues in your foot, it was cool to see the bones in your foot move. The fluoroscope achieved this magic through x-rays. By the 1950s, people understood that being exposed to lots of x-rays was really bad for people. Overexposure to x-rays increases the odds you get various cancers. In 1957, Pennsylvania started a pattern of governments banning the devices(http://www.smithsonianmag.com/history-archaeology/Heres_Looking_at_You_Kids.html). The fears were along the lines of the following:

  1. Growing people (kids) shouldn’t be exposed to this many x-rays.
  2. Lots of x-rays were taken of the salespeople.

Think about #2. According to http://www.orau.org/ptp/collection/shoefittingfluor/shoe.htm, people got radiation burns and cancers from lots of exposures.

Many shoe salespersons put their hands into the x-ray beam to squeeze the shoe during the fitting. As a result, one saleswoman who had operated a shoe fitting fluoroscope 10 to 20 times each day over a ten year period developed dermatitis of the hands. One of the more serious injuries linked to the operation of these machines involved a shoe model who received such a serious radiation burn that her leg had to be amputated (Bavley 1950).

Interestingly enough, the Transportation Security Administration has installed thousands of x-ray machines as full body scanners. Frequent travelers are getting x-rayed several times a week. TSA employees are getting nearby exposure scans hundreds of times per day. Because of concerns around the health effects, a case was brought and was decided against the TSA that they need to figure out if these machines are safe. Our executive branch needs to enforce this ruling, but so far have chosen not to enforce it.

If you have some time today, I recommend that you go to https://petitions.whitehouse.gov/petition/require-transportation-security-administration-follow-law/tffCTwDd and sign the petition to get the executive branch to carry out the decision of the judicial branch.

Leave a comment

Validating a WRAP ACS token in node.js

A few friends and I are building a system for home automation. Specifically, it is an application that opens and closes a garage door. One of the design decisions was to write the server side in node.js but to use Azure when it made sense. One of the Azure features we are using is the Access Control Service. When a client presents a token, you need to make sure that the signature on that token is valid. That turns out to be fairly interesting if you are new to node.js and have never used it before. I fit that model well. After a lot of tinkering and learning, I was able to write a function that validated a wrap_access_token using node.js and some associated, standard libraries. Here is the code, in its entirety. I include some ‘test’ code as well to allow others to verify results. I’ve already rotated the ACS signing key so that I don’t breach security too badly. This whole thing works surprisingly well.

In case you can’t read the code too well, here is what it does:

1. Parse the token into it’s constituent parts.

2. Pass the wrap_access_token to the function, along with the associated key.

Within the function:

1. Remove the signature part from the token since we need to verify that we generate the same signature. Since the signature is generated based on the bytes that precede it, the signature can’t be part of itself (this part is obvious when you think of it; the hard part is remembering to think of it!)

2. Unescape the signature and remember the base64 version of the signature, which is really just a byte array.

3. Generate the SHA256 HMAC signature using the shared secret/key.

4. Verify that the base64 encoding of the digest that we generated matches the one that was sent it.

5. If the signature passed in matches the one we generated, then the other entity knows the secret and can be trusted to have signed the tokens.

6. Party on, because the claims are valid.

The code would next need to split out the claims. The claims are just form-encoded key value pairs within the wrap_access_token. That step is left as an exercise for the reader.

var crypto = require(‘crypto’);
var util = require(‘util’);
var querystring = require(‘querystring’);
var buffer = require(‘buffer’);

function ValidateToken(token, key){
var hmacToken = “&HMACSHA256=”;
var indexOfToken = token.indexOf(hmacToken) + hmacToken.length;
var swtSignature = querystring.unescape(token.substr(indexOfToken, token.length – indexOfToken));
var signedPiece = token.substr(0, indexOfToken – hmacToken.length);
var buffer = new Buffer(key, encoding=”base64″);
var hmac = crypto.createHmac(“sha256″, buffer);
hmac.update(signedPiece);
var digest = hmac.digest(encoding=”base64”);
return digest == swtSignature;
}

var theToken = “wrap_access_token=developersmackdown.garage%3dOpenClose%26http%253a%252f%252fschemas.microsoft.com%252faccesscontrolservice%252f2010%252f07%252fclaims%252fidentityprovider%3dhttps%253a%252f%252ffriseton.accesscontrol.windows.net%252f%26Audience%3dhttp%253a%252f%252fcontosocontacts%252f%26ExpiresOn%3d1325287532%26Issuer%3dhttps%253a%252f%252ffriseton.accesscontrol.windows.net%252f%26HMACSHA256%3dSrgqXJv9pkxjweT2Lr%252bIV%252fGAncqIc34SnbrHdbr3VOQ%253d&wrap_access_token_expires_in=5999”;
var theData = querystring.parse(theToken, sep=’&’, eq=’=’);
var theKey = “Bn7TfLML5wK+R5TAa2VrO/9JANwuk3lzt/ykc4no+h0=”;

util.puts(ValidateToken(theData.wrap_access_token, theKey));

Leave a comment

REST Presentation at Chicago Software Development Community in Oakbrook

Thanks again to everyone who showed up for my presentation on REST at the Microsoft Store in Oakbrook. I’ve posted the slides and demos here. It was a great time. I’ve never presented in a store, never had a component of the “audience” that was just shopping either. It was an interesting, unique experience to say the least! I also enjoyed the conversations afterwards.

Leave a comment

My Windows Azure Caching Service talk from DevConnections

I just presented my Windows Azure Caching Service talk. Thanks to everyone who attended. The audience was small, but I love that you all asked so many great questions. Here are the slides and demos from the talk. I’ll be giving this talk again at the Midwest Cloud Computing User Group in the Chicago area on November 15. You can register for it at http://www.communitymegaphone.com/ShowEvent.aspx?EventID=4709.

The slides and demos from the content at DevConnections is here.

Leave a comment

Talk and demos from CNUG, AppFabric Talk

Last night I had a chance to speak about Windows Azure AppFabric at the Chicago .NET Users’ Group. Thanks to everyone who came out! I had a great time. A few of you really wanted the slides ASAP. I’ve cleaned out my keys and namespaces from the demos, so they don’t run at the moment (but they will build!). You can get them here: https://friseton.blob.core.windows.net/downloads/CNUG-AppFabric-2011-07-20.zip.

You’ll need to install a few things and create a few accounts if you want to run any of the demos:

Tools:

1. Getting started links for Windows Azure: http://www.microsoft.com/windowsazure/learn/getstarted/

2. Windows Azure AppFabric SDK 1.0: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19925 (for production AppFabric)

3. Windows Azure AppFabric SDK 2.0: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17691 (for the CTP bits: queues, topics, etc.)

4. More training on Windows Azure: https://www.pluralsight-training.net/microsoft/OLT/subscribe/Subscribe1.aspx?freetrial=true&planHint=Monthly (10 day free trial– totally worth it, but I am an instructor there too;) )

Leave a comment

AppFabricLabs and the ServiceBus

This week, the Windows Azure AppFabricLabs was updated. The major updates are that the Service Bus labs environment now uses v2 of the Access Control Service and topics/queues have been created. This pushes the number of queueing solutions on Azure to 3:

* Queue Storage

* Message Buffer

* Queues

The main difference between the types of storage relates to size and usage patterns. Queue storage allows for messages up to 8 KB in size and is primarily intended for applications running on Azure. The service only accepts one type of credentials, and you probably don’t want to share those.

The Message Buffer stores messages of up to 60KB for about a minute. It is great for volatile queues as a short lived rendezvous point for exchanging messages. This service lives on the Service Bus and allows for authentication with the Access Control Service.

The Queues implementation in the Service Bus allows for larger messages (up to 256 KB) which can last for a longer period of time. Interacting with the queue feature is pretty simple. Go to the https://portal.appfabriclabs.com page and allocate a Service Bus namespace. The ‘Hello, World’ for the queue looks like this:

static void Main(string[] args)
{
  var sbNamespace = "your namespace";
  var credential = TransportClientCredentialBase.
    CreateSharedSecretCredential("owner", "[your key]");
  var uri = ServiceBusEnvironment.CreateServiceUri("https", sbNamespace, 
    string.Empty);
  var client = new ServiceBusNamespaceClient(uri, credential);
  var messagingFactory =
    MessagingFactory.Create(ServiceBusEnvironment.CreateServiceUri("sb", 
    sbNamespace, string.Empty), credential);
  var queue = client.CreateQueue("demo");
  var queueClient = messagingFactory.CreateQueueClient(queue);
  var sender = queueClient.CreateSender();
  sender.Open();
  sender.Send(BrokeredMessage.CreateMessage("test"));
  sender.Close();
  var receiver = queueClient.CreateReceiver();
  receiver.Open();
  var message = receiver.Receive();
  receiver.Close();
  Console.WriteLine(message.GetBody<string>());
}

Leave a comment