Horizontal List Boxes in Silverlight

A list box in XAML does not just have to look like a normal list box with just a single line of data in each row. You can place multiple rows into the list box, and you can even turn the list box so it displays the data horizontally instead of vertically (see Figure 1).

Horizontal ListBox
Figure 1: A List Box can display its data horizontally

The Product Class

For this example, I will be using a simple Product class with three properties, and a collection class of Product objects using the Generic List class. You can create this sample by creating a Product class as shown in the following code:

public class Product {
  public Product() { }

  public Product(string name, string type, decimal price)
  {
    this.ProductName = name;
    this.ProductType = type;
    this.Price = price;
  }

  public string ProductName { get; set; }
  public string ProductType { get; set; }
  public decimal Price { get; set; }
}

Create a collection class that initializes a property called DataCollection with some sample data as shown in the code below:

public class Products : List<Product> {
  public Products() {
    BuildCollection();
  }

  public List<Product> DataCollection { get; set; }

  List<Product> BuildCollection() {
    DataCollection = new List<Product>();

    DataCollection.Add(new Product(
      "Haystack Code Generator for .NET", "Product", 799));
    DataCollection.Add(new Product(
      "Fundamentals of N-Tier eBook", "Book", 19.95));

    // MORE PRODUCTS HERE – REMOVED FOR BREVITY

    return DataCollection;
  }
}

Create Instance of Product Class in XAML

The first thing you need to do is to create an instance of the Products collection class in your XAML. In your MainPage.xaml, add an xml namespace to the name of your project as shown here:

xmlns:data="clr-namespace:SLHorizontal "

Next you create an instance of the Products class in XAML. The constructor for the Products class will create the initial collection of product objects.

<UserControl.Resources>
  <data:Products x:Key="productCollection" />
</UserControl.Resources>

Create Horizontal List Box

Now it is time to create the List Box and connect it to the static resource you created in the above XAML. Below is the XAML used for the complete list box. After you look at this XAML you will learn about each of the various pieces that make up the horizontal list box.

<ListBox Height="200"
          Name="lstData"
          Background="Beige"
          ItemsSource="{Binding
                  Source={StaticResource productCollection},
                  Path=DataCollection}">
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Border BorderBrush="Gray"
              Margin="6,2,6,2"
              Padding="4"
              BorderThickness="2"
              CornerRadius="5"
              Background="Aqua"
              Width="250">
        <StackPanel Orientation="Vertical"
                    HorizontalAlignment="Left"
                    Margin="8">
          <TextBlock FontSize="16"
                      TextWrapping="Wrap"
                      Text="{Binding Path=ProductName}" />
          <StackPanel Orientation="Horizontal">
            <TextBlock FontSize="12"
                        Text="Type: " />
            <TextBlock FontSize="12"
                        Text="{Binding Path=ProductType}" />
            <TextBlock FontSize="12"
                        Margin="10,0,0,0"
                        Text="Price: " />
            <TextBlock FontSize="12"
                        Text="{Binding Path=Price,
                                      StringFormat=c}" />
          </StackPanel>
        </StackPanel>
      </Border>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Let’s now break down each of the areas of the ListBox XAML shown above. First, notice the ItemsSource property is simply setup to reference the static resource you created named “productCollection”. This is the Products collection class. The Path attribute refers to the DataCollection property within the Products collection that was created in the constructor of the Products class.

<ListBox Height="200"
          Name="lstData"
          Background="Beige"
          ItemsSource="{Binding
                  Source={StaticResource productCollection},
                  Path=DataCollection}">

Next, and probably the most important part of the XAML is the ItemsPanel element. While you may have used the ItemsTemplate element before to create the layout of each row in the list, the ItemsPanel is used to control the overall look of the list box itself, not each individual item. When Microsoft defined the default look for the list box, they used a normal StackPanel control which has its Orientation set to vertical. However, we want our list box to be display horizontally so you simply need to set the ItemsPanelTemplate with a StackPanel that has its Orientation attribute set to Horizontal. This is what makes the list box display each row horizontally.

<ListBox.ItemsPanel>
  <ItemsPanelTemplate>
    <StackPanel Orientation="Horizontal" />
  </ItemsPanelTemplate>
</ListBox.ItemsPanel>

Finally you have the definition for each “row” in the list box defined in the ItemsTemplate. Each row is encased in a <Border> control to give each row a separate and distinct look with a rounded border and an aqua blue background. Next, there is a <StackPanel> control to display the data vertically. The product name is displayed in a TextBlock with text wrapping turned on. Next there is another <StackPanel> control with its orientation set to horizontal to display the product type and price of each product side by side.

<Border BorderBrush="Gray"
        Margin="6,2,6,2"
        Padding="4"
        BorderThickness="2"
        CornerRadius="5"
        Background="Aqua"
        Width="250">
  <StackPanel Orientation="Vertical"
              HorizontalAlignment="Left"
              Margin="8">
    <TextBlock FontSize="16"
               TextWrapping="Wrap"
               Text="{Binding Path=ProductName}" />
    <StackPanel Orientation="Horizontal">
      <TextBlock FontSize="12"
                 Text="Type: " />
      <TextBlock FontSize="12"
                 Text="{Binding Path=ProductType}" />
      <TextBlock FontSize="12"
                 Margin="10,0,0,0"
                 Text="Price: " />
      <TextBlock FontSize="12"
                 Text="{Binding Path=Price,
                                StringFormat=c}" />
    </StackPanel>
  </StackPanel>
</Border>

Notice in the text block that displays the actual price the use of the StringFormat attribute to display the decimal value for the price in a currency format. This is accomplished using “c” for the value passed to StringFormat.

Summary

In this blog entry you learned how to create a list box that displays data horizontally instead of vertically. The ListBox control in Silverlight is very flexible and you are really only limited by your imagination. We have used the ListBox for simulating Tab controls, for menu systems, and we have even used a ListBox as each row within another list box.

NOTE: You can download the complete sample code (in both VB and C#) at my website. http://www.pdsa.com/downloads. Choose Tips & Tricks, then "Horizontal List Box in Silverlight" from the drop-down.

Good Luck with your Coding,
Paul Sheriff

** SPECIAL OFFER FOR MY BLOG READERS **
Visit http://www.pdsa.com/Event/Blog for a free videos on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

 

7 Comments

Comments have been disabled for this content.